/* ---- Your Favorite Team's Favorite Team ----
   A map of where a visiting team takes the empty seats out of a park, on
   Elbow Room. Styled the way Elbow Room is: chart elements carry classes and
   the stylesheet owns their colour, so both themes follow without the script
   re-reading tokens. */

/* Your Favorite Team's Favorite Team.  The picker is the Elbow Room chip grid
   with one team pressed at a time; the park pair below it is the comparison. */

.ft-bar { display: flex; flex-wrap: wrap; gap: 18px 24px; align-items: flex-end; margin-bottom: 14px; }
.ft-control { display: flex; flex-direction: column; gap: 5px; }
.ft-legend { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-muted); }
.ft-control select {
  font: inherit; font-size: 13px; padding: 6px 8px; min-width: 190px;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--rule); border-radius: 5px;
}

@media (max-width: 480px) { .ft-control select { min-width: 0; width: 100%; } }

.ft-keys { display: flex; flex-wrap: wrap; gap: 8px 20px; margin: 2px 0 8px; }

/* The lede sits in --ink-2; a bold run inside it lifts to --ink, the same way
   the sentence under the map treats its own bold. */
.lede strong { color: var(--ink); font-weight: 700; }

/* ---- the map ----
   Styled the way Elbow Room is: chart elements carry classes and the
   stylesheet owns their colour, so both themes follow without the script
   re-reading tokens. The heat canvas underneath still reads tokens, because
   it paints pixels. */
.fm { margin: 0 0 8px; position: relative; }
.fm-stack { position: relative; }
.fm-canvas { position: absolute; inset: 0; width: 100%; height: auto; display: block; }
/* The canvas is absolutely positioned, so it paints above any static sibling
   whatever the document order says. The SVG has to be positioned too or the
   heat covers the country, its markers and its labels wherever the field is
   opaque. This named #fm-svg, which stopped existing when the map it belonged
   to was replaced, and every label vanished under the heat. Match the layer by
   position in the stack instead, so a rename cannot silently undo it. */
.fm-stack > :not(canvas) { position: relative; }
.fm-map { display: block; width: 100%; height: auto; }

/* A geographic cue, not a chart element, so it stays a whisper over whatever
   the field is doing. --grid at full strength ran 1.00:1 on the neutral band
   and 4.08:1 against the deepest blue -- invisible where there was no heat and
   loudest exactly where there was most. The ink at a low alpha is almost flat
   instead, 1.19 to 1.29 in light and 1.11 to 1.45 in dark, so no state line is
   ever the brightest thing on the map.

   It also has to stay out of the colour's way. At 12% a line shifted the pixel
   under it by 29 of 255 -- an eleven percent darkening of everything it
   crossed, over a network of forty-nine paths -- which read as the heat losing
   its punch rather than as the borders fading. 6% halves that. */
.fm-state { fill: none; stroke: var(--ink); stroke-opacity: .06; stroke-width: 0.7; }
.fm-anchor { stroke: var(--rule); stroke-width: 0.9; }
.fm-anchor-dot { fill: var(--rule); }

.fm-team { cursor: pointer; }
.fm-hit { fill: transparent; }            /* the click target, invisible and generous */
/* Thirty-one opaque discs punched into the field is the other half of what
   dulls it, so they are only as big as they need to be to stay readable. The
   click target is the separate .fm-hit circle and does not shrink with them.

   Fixed colours, not measured ones: the dot's job is to say whether this team
   is the one you picked. --ink and --plane swap between themes on their own,
   so it reads as a black dot among white in light and a white dot among black
   in dark. Disc and ring are always opposites, so one of them carries against
   any ground the field puts underneath. */
.fm-dot { fill: var(--plane); stroke: var(--ink); stroke-width: 1.6; }
.fm-me .fm-dot { fill: var(--ink); stroke: var(--plane); stroke-width: 2; }
/* A team with no season in the span: no disc to fill, so it stays an outline. */
.fm-flat .fm-dot { fill: none; stroke: var(--ink-muted); stroke-width: 1; }
/* The one mark that says which team you picked, so it is the strongest thing
   on the marker rather than the faintest. At 35% opacity and a single unit it
   lost to a dark disc on cold ground: asked which team was selected, the
   honest answer was whichever marker happened to sit on the deepest blue. */
/* A logo marker: the team's mark on a disc of the page's ground, outlined in
   ink so the disc holds its edge over pale heat as well as deep. */
.fm-disc { fill: var(--surface); stroke: var(--ink); stroke-width: 1.2; }
.fm-flat .fm-disc { stroke: var(--ink-muted); }
.fm-flat .fm-logo { opacity: .4; }
.fm-team:hover .fm-disc { stroke-width: 2.2; }
.fm-team:focus-visible .fm-disc { stroke: var(--accent); stroke-width: 2.6; }
.fm-ring-halo { fill: none; stroke: var(--plane); stroke-width: 4.2; }
.fm-ring { fill: none; stroke: var(--ink); stroke-width: 2; }
.fm-abbr {
  fill: var(--ink-2); font: 700 10.5px var(--sc-text); letter-spacing: .02em;
  /* The halo goes under the glyph so the letter keeps its own weight, and it
     stays near a tenth of the type size: a 2.6 stroke on 9px type renders as
     three pixels of white into a ten pixel letter and closes the counters, so
     the word turns into a blob at the size the map is actually read at. */
  stroke-width: 1.2px; stroke-linejoin: round; paint-order: stroke fill;
}
.fm-me .fm-abbr { font-weight: 800; }
.fm-team:hover .fm-dot { stroke-width: 2.6; }
.fm-team:focus-visible { outline: none; }
.fm-team:focus-visible .fm-dot { stroke: var(--accent); stroke-width: 3; }

.fm-ramp { display: inline-flex; gap: 0; border-radius: 3px; overflow: hidden; }
.fm-ramp i { width: 26px; height: 12px; display: block; }

.fm-say { font-size: 12.5px; line-height: 1.5; color: var(--ink-2); margin-top: 10px; max-width: 92ch; }
.fm-say strong { color: var(--ink); font-weight: 700; }

/* The svg scales to its container, so its text scales with it: at 375px wide
   a 9-unit label renders under 3px. These are user units, not pixels. */
@media (max-width: 640px) {
  .fm-abbr { font-size: 21px; stroke-width: 2.4px; }
  .fm-dot { stroke-width: 2.6; }
  .fm-flat .fm-dot { stroke-width: 1.8; }
  .fm-ramp i { width: 18px; }
}

/* The season range, the same two-handle track Elbow Room uses. */
.fm-years { display: flex; align-items: center; gap: 10px; }
.fm-range { position: relative; width: min(260px, 40vw); height: 22px; }
.fm-track, .fm-fill { position: absolute; top: 9px; height: 4px; border-radius: 2px; }
.fm-track { left: 0; right: 0; background: var(--grid); }
.fm-fill { background: var(--accent); }
.fm-range input[type="range"] {
  position: absolute; left: 0; top: 0; width: 100%; height: 22px; margin: 0;
  background: none; pointer-events: none; -webkit-appearance: none; appearance: none;
}
.fm-range input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; pointer-events: auto; width: 16px; height: 16px; border-radius: 50%;
  background: var(--surface); border: 2px solid var(--accent); cursor: pointer;
}
.fm-range input[type="range"]::-moz-range-thumb {
  pointer-events: auto; width: 16px; height: 16px; border-radius: 50%;
  background: var(--surface); border: 2px solid var(--accent); cursor: pointer;
}
.fm-range input[type="range"]::-moz-range-track { background: none; }
#fm-span { font-size: 13px; color: var(--ink-2); font-variant-numeric: tabular-nums; min-width: 82px; }
/* Back to the league. Disabled when the league is already what is showing, so
   the control says whether there is anything to clear. */
.fm-clear {
  font: inherit; font-size: 12px; padding: 4px 10px; cursor: pointer;
  color: var(--ink-2); background: var(--surface);
  border: 1px solid var(--rule); border-radius: 5px;
}
.fm-clear:hover:not(:disabled) { color: var(--ink); border-color: var(--accent); }
.fm-clear:disabled { color: var(--ink-muted); cursor: default; opacity: 1; }

/* ---- both ways round: the reciprocal grid ----
   Home across the top, away down the side, in divisions. Follows the
   leaderboard's table: its own scroller, a sticky head, separate borders. */
.ftm-title { font-family: var(--sc-display); font-weight: 800; font-size: 30px;
  line-height: 1.05; letter-spacing: .005em; margin: 36px 0 14px; }

.ftm-wrap { overflow-x: auto; background: var(--surface); border: 1px solid var(--ring); border-radius: 8px; }
/* Fills the box when there is room and scrolls when there is not. The
   min-width is the corner plus thirty columns at their narrowest: without it
   a fixed layout divides whatever space it is given, the columns fall under
   the width of "-0.04", and the numbers run into each other. */
table.ftm {
  border-collapse: separate; border-spacing: 0; font-size: 11px; font-weight: 600;
  font-variant-numeric: tabular-nums; width: 100%; min-width: 1000px;
  table-layout: fixed;
}
/* The two fixed columns on the left: the turned division label and the team.
   A fixed layout reads its widths from the first row, and the corner spans
   both of them, so the widths are stated here instead. */
col.ftm-cdiv { width: 20px; }
col.ftm-cname { width: 74px; }
/* Only an unshaded cell needs a colour of its own. */
/* The diagonal carries a shaded figure now, so it keeps the ink its fill was
   paired with like any other cell. */
table.ftm td:not([class*=" p"]) { color: var(--ink-2); }
table.ftm td, table.ftm th { overflow: hidden; }
table.ftm th, table.ftm td { padding: 0; text-align: center; white-space: nowrap; }

.ftm thead th { position: sticky; z-index: 2; background: var(--surface); }
.ftm thead tr:first-child th { top: 0; }
.ftm thead tr:nth-child(2) th { top: 19px; }
/* Columns are fixed in the league's brand order, so one band names that across
   the top and one turned band names the row order down the side. */
.ftm-band, .ftm-aband { color: var(--ink-muted); font-weight: 600;
  font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase; }
.ftm-band { height: 19px; border-bottom: 1px solid var(--grid); }
.ftm-aband { position: sticky; left: 0; z-index: 1; background: var(--surface);
  border-right: 1px solid var(--grid); }
.ftm-aband span { display: inline-block; writing-mode: vertical-rl; transform: rotate(180deg); }
.ftm-h { width: 30px; min-width: 30px; height: 22px; color: var(--ink-2); font-weight: 700;
  border-bottom: 1px solid var(--rule); cursor: pointer; }
.ftm-h:hover { color: var(--ink); }
/* The column the grid is ordered by. */
.ftm-h.ftm-sorted { color: var(--ink); box-shadow: inset 0 -2px 0 var(--accent); }
/* The grid's top-left corner. It carries no label -- it is here for the
   sticky position and the two rules the header and the row labels meet at. */
.ftm-corner {
  left: 0; top: 0; z-index: 4;
  font-size: 9.5px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-muted); font-weight: 600; border-bottom: 1px solid var(--rule);
  border-right: 1px solid var(--rule);
}
/* Centred, like every other cell in the grid: the rule on table.ftm th sets
   it and this one does not fight it. */
.ftm-a {
  position: sticky; left: 20px; z-index: 1; background: var(--surface);
  padding: 0 4px; height: 20px;
  color: var(--ink-2); font-weight: 700; cursor: pointer;
  border-right: 1px solid var(--rule);
}
.ftm-a:hover { color: var(--ink); }
/* No colour here: a .pN fill carries the --iN ink meant to sit on it, and
   .ftm-c would override it -- same specificity, later in the cascade. */
.ftm-c { height: 20px; border-bottom: 1px solid var(--grid); }
/* A team against itself: the park's own elbow room, which is the same unit as
   its neighbours and a different measurement. An outline marks it as such
   without taking the fill away from the ramp. */
.ftm-self { box-shadow: inset 0 0 0 1px var(--rule); }
/* --row-hover is translucent, so setting it as the background replaces the
   opaque one the sticky cells need and the grid scrolls into view behind
   them. Tint over --surface instead of in place of it. */
.ftm tr.ftm-on .ftm-a, .ftm th.ftm-on {
  color: var(--ink); background-color: var(--surface);
  background-image: linear-gradient(var(--row-hover), var(--row-hover));
}
.ftm tr.ftm-on td { box-shadow: inset 0 -1px 0 var(--rule); }

@media (max-width: 640px) {
  table.ftm { font-size: 9.5px; }
  .ftm-h { width: 28px; min-width: 28px; }
  col.ftm-cdiv { width: 18px; }
  col.ftm-cname { width: 58px; }
  .ftm-a { left: 18px; }
}
/* Measured but not separable from chance. The shading is the site's, so the
   ink that comes with it stays: certainty is carried by weight alone, and an
   earlier attempt at 55% opacity put the figure at 2.11:1 on its own cell. */
.ftm-faint { font-weight: 400; }
.ftm-c { font-weight: 700; }

/* ---- perceived brand ----
   The map and the board are the two halves of one figure: the selected team on
   the road, and their own park judging everyone else. The board keeps a fixed
   column so the map takes whatever is left, and the two stack under 900px. */
.fm-split {
  display: grid; grid-template-columns: minmax(0, 1fr) 272px; gap: 20px;
  align-items: start;
}
/* The rows divide whatever height the map has rather than carrying a fixed
   one, so the list ends level with the map at twenty-nine rows or thirty. */
/* The map sets the height -- it has an aspect ratio to keep -- and the board
   stretches to meet it. Stretching both instead lets the longer list pull the
   map's box open and leaves dead space under the country. */
.fb { align-self: stretch; display: flex; flex-direction: column; }
.fb-list { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.fb-title { font-family: var(--sc-display); font-weight: 800; font-size: 21px;
  line-height: 1.05; margin: 0 0 2px; }
.fb-sub { color: var(--ink-2); font-size: 12px; margin: 0 0 8px; }
.fb-head, .fb-row {
  display: grid; grid-template-columns: 18px minmax(0, 1fr) 34px 44px;
  align-items: center; gap: 6px;
}
.fb-head {
  font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-muted); font-weight: 600; padding: 0 0 4px;
  border-bottom: 1px solid var(--rule);
}
.fb-head span:nth-child(3), .fb-head span:nth-child(4) { text-align: center; }
.fb-head span:nth-child(2) { text-align: left; }
.fb-list { list-style: none; margin: 0; padding: 0; }
/* flex-basis 0 and a set line-height keep the list's own height down to thirty
   times the minimum, so it is the map that sizes the row and the rows that
   divide it, not the other way about. */
.fb-row {
  flex: 1 1 0; min-height: 14px; line-height: 1; font-size: 11.5px; cursor: pointer;
  border-bottom: 1px solid var(--grid); font-variant-numeric: tabular-nums;
}
.fb-row:hover { background: var(--row-hover); }
.fb-n { color: var(--ink-muted); font-size: 9.5px; font-weight: 600; text-align: right; }
.fb-t { color: var(--ink-2); font-weight: 700; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.fb-row:hover .fb-t { color: var(--ink); }
/* The index carries the site's ramp, which brings the --iN ink with it. */
.fb-i { font-style: normal; font-weight: 700; text-align: center; border-radius: 3px;
  line-height: 15px; height: 15px; }
.fb-s { font-style: normal; color: var(--ink-2); font-size: 10.5px; text-align: center; }

/* Thirty rows at their minimum stand 497px tall, which is a 801px map, which is
   a 1141px window. Narrower than that the board would outrun the country and
   leave dead space beneath it, so they stack instead. */
@media (max-width: 1140px) {
  .fm-split { grid-template-columns: minmax(0, 1fr); }
  /* Stacked, the list has no map to match, so the rows take a readable height
     of their own rather than collapsing onto the minimum. */
  .fb { max-width: 420px; }
  .fb-row { min-height: 22px; }
}


/* The local term is a movement in rank: up this park's order against the
   league's, down it, or level. Neutral ink, so the arrow does not compete with
   the ramp on the index beside it. */
.fb-up, .fb-dn, .fb-lv { font-size: 7.5px; vertical-align: 1px; margin-right: 1px; }
.fb-lv { color: var(--ink-muted); font-size: 10.5px; vertical-align: 0; margin: 0; }

/* The selected team's own row. It is the one row not built from a visit, and
   the one the reader came for. */
.fb-row.fb-self {
  background-color: var(--surface);
  background-image: linear-gradient(var(--row-hover), var(--row-hover));
  box-shadow: inset 2px 0 0 var(--accent);
}
.fb-row.fb-self .fb-t { color: var(--ink); font-weight: 800; }
