{% load static%}

/* DESIGN TOKENS — pill/zone palette (color = severity, word = tier) */
:root {
  --riot-blue: #2f5496;
  --secured-text: #0f5132;
  --secured-bg: #d1e7dd;
  --secured-accent: #198754;
  --caution-text: #664d03;
  --caution-bg: #fff3cd;
  --caution-accent: #cc8a00;
  --out-text: #842029;
  --out-bg: #f8d7da;
  --out-accent: #c00000;
  --moot-gray: #adb5bd;
  /* ink/rule neutrals, harvested with the webpage_new chrome (2026-08-12) */
  --ink: #212529;
  --ink-soft: #495057;
  --ink-muted: #6c757d;
  --ink-faint: #8a8f98;
  --rule: #e3e7ef;
  --rule-soft: #eef1f6;
}

/* Self-hosted Barlow (was 2x Google Fonts <link> in base.html). Latin subset only --
   the site is English-only, no need for the vietnamese/latin-ext subsets Google serves. */
@font-face {
  font-family: "Barlow";
  font-style: normal;
  font-weight: 400;
  src: url("../fonts/Barlow-Regular.woff2") format("woff2");
}

/* GENERAL PAGE STYLING */
html, body {
  font-family: "Barlow";
  margin: 0;
  padding: 0;
  font-size: 16px;
}

footer {
  background: #f5f5f5;
}

h1 {
  font-size: 34px;
  color: #2f5496;
  font-weight: 900;
}

h2 {
  font-size: 26px;
  color: #2f5496;
  font-weight: 800;
}

h3 {
  font-size: 21px;
  color: #2f5496;
  font-weight: 700;
}

h4 {
  font-size: 20px;
  font-weight: 700;
}

h5 {
  font-size: 20px;
  font-weight: 600;
}

/* Intentionally large intro/lead copy (the old global `span { font-size: 24px }`
   inflated every unstyled span, including scenario table cells; scoped now) */
.lead-text {
  font-size: 19px;
}

/* TWO-TIER SITE HEADER (page-shell rider)
   Tier 1 is global (logo, league tabs, About RIOT); tier 2 is the selected
   league's own sub-nav and is absent everywhere else. The whole header is ONE
   sticky element so the two tiers stay locked together while scrolling --
   making each tier sticky separately lets tier 2 slide under tier 1.
   Following context/design/inspo, the colour lives in the active tab and the
   rest stays quiet; no skew, no hamburger. */
.site-header {
  background: #fff;
  border-bottom: 1px solid #e2e6ee;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .06);
}

.tier1 {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0 1.25rem;
  min-height: 58px;
}
.tier1-brand {
  flex: none;
  line-height: 0;
}
.tier1-brand img {
  width: 96px;
  height: 48px;
}

/* Tabs scroll sideways on a narrow screen rather than collapsing behind a
   toggle: the leagues ARE the primary navigation. -webkit-overflow-scrolling
   keeps the swipe native on iOS. */
.tier1-tabs,
.tier2 {
  display: flex;
  align-items: center;
  gap: 2px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.tier1-tabs::-webkit-scrollbar,
.tier2::-webkit-scrollbar {
  display: none;
}
.tier1-tabs {
  flex: 1 1 auto;
}
.tier1-end {
  flex: none;
  margin-left: auto;
}

.tier1-tab,
.tier1-link {
  flex: none;
  padding: .45rem .85rem;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: .01em;
  color: #5a6472;
  text-decoration: none;
  white-space: nowrap;
  transition: color .15s, background .15s;
}
.tier1-tab:hover,
.tier1-link:hover {
  background: #eef2f9;
  color: var(--riot-blue);
  text-decoration: none;
}
.tier1-tab.active {
  background: var(--riot-blue);
  color: #fff;
}
.tier1-link.active {
  color: var(--riot-blue);
  background: #eef2f9;
}

/* Tier 2 reads as a sub-level: smaller, quieter, underlined active state rather
   than a second filled pill competing with the league tab above it. */
.tier2 {
  gap: .25rem;
  padding: 0 1.25rem;
  border-top: 1px solid #eef0f5;
  background: #fafbfd;
  min-height: 40px;
}
.tier2-tab {
  flex: none;
  padding: .3rem .1rem;
  margin-right: 1.1rem;
  font-size: 13px;
  font-weight: 600;
  color: #6c757d;
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
}
.tier2-tab:hover {
  color: var(--riot-blue);
  text-decoration: none;
}
/* Column guide: pinned right on tier 2. margin-left:auto against the tab row,
   so it holds the far edge on a wide screen and simply scrolls with the tabs on
   a narrow one. The mark is the repo's own info icon, resized to the 72px the
   18px slot actually needs -- it shipped at 4096px, a quarter of a megabyte to
   draw a circle the size of a full stop. */
.tier2-info {
  flex: none;
  margin-left: auto;
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  padding: .15rem .5rem .15rem .35rem;
  border: 1px solid #d7dce5;
  border-radius: 999px;
  background: #fff;
  font-size: 12px;
  font-weight: 600;
  color: #6c757d;
  text-decoration: none;
  white-space: nowrap;
}
.tier2-info:hover {
  color: var(--riot-blue);
  border-color: var(--riot-blue);
  text-decoration: none;
}
.tier2-info img {
  display: block;
}
.tier2-tab.active {
  color: var(--riot-blue);
  border-bottom-color: var(--riot-blue);
}

@media (max-width: 575px) {
  .tier1 {
    gap: .5rem;
    padding: 0 .6rem;
    min-height: 52px;
  }
  .tier1-brand img {
    width: 72px;
    height: 36px;
  }
  .tier1-tab,
  .tier1-link {
    padding: .4rem .6rem;
    font-size: 13px;
  }
  .tier2 {
    padding: 0 .6rem;
  }
}

/* FOOTER CONTENT STYLING */
/* The three social marks are inline SVG filled with currentColor, so hover is
   one color transition instead of a second 4096x4096 PNG. This replaced the
   #facebook/#twitter/#youtube `content: url()` swap pairs (harvest from
   webpage_new, 2026-08-17); the intrinsic-size trap those rules worked around
   is gone with them, because an inline <svg> has no intrinsic size to fight.

   40px hit area around a 19px mark: the mark reads at the same weight as the
   old 60px PNGs while giving the link a touch target that clears 40px. */

.social-row {
  display: flex;
  justify-content: center;
  gap: .35rem;
}
.social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  color: var(--ink-faint);
  transition: color .12s ease, background .12s ease;
}
.social-link svg {
  width: 19px;
  height: 19px;
  fill: currentColor;
}
.social-link:hover,
.social-link:focus {
  color: var(--riot-blue);
  background: var(--rule-soft);
}

.copyright {
  color: var(--ink-faint);
  font-size: 13px;
  margin: 0 0 .15rem;
}
/* The entity line closes the stack, so it gets the only margin-bottom and a
   hair more separation from the two research lines above it. */
.copyright--entity {
  margin-top: .5rem;
}



/* CIRCLE CONTENT STYLING */
/* The swap images are 4096x4096; `content: url()` makes the browser use the
   intrinsic size, so the HTML width/height attributes don't reliably hold.
   Size them here explicitly. */

#csm {
  content: url("../img/misc/csm-before.png");
  width: 150px;
  height: 150px;
}

#csm:hover {
  content: url("../img/misc/csm-after.png");
}

#smu {
  content: url("../img/misc/smu-before.png");
  width: 150px;
  height: 150px;
}

#smu:hover {
  content: url("../img/misc/smu-after.png");
}


/* SCROLLABLE STANDINGS TABLE w FIXED HEADER STYLING */
.table-fixed tbody {
    height: 300px;
    overflow-y: auto;
    width: 100%;
}

.table-fixed thead,
.table-fixed tbody,
.table-fixed tr,
.table-fixed td,
.table-fixed th {
    display: block;
}

.table-fixed tbody td,
.table-fixed tbody th,
.table-fixed thead > tr > th {
    float: left;
    position: relative;

    &::after {
        content: '';
        clear: both;
        display: block;
    }
}

.updated-timestamp {
  font-size: 15px;
  color: gray;
  font-weight: 100;
  white-space: nowrap;
  display: inline-block;
}

.team-name {
  font-size: 16px;
  color: black;
  font-weight: 600;
}

/* ESPN-style responsive identity: the short name by default, the 3-letter code
   when the viewport gets narrow (small screens or heavy zoom). Breakpoint at
   768px so the code kicks in on moderate zoom / tablets, not only at extreme
   300%+ zoom.

   The hidden tier is .tn-display, NOT .tn-mascot: team_label renders the
   `display` field and stopped emitting a mascot tier, so this rule matched
   nothing and BOTH names showed below 768px -- "SSGSSG" for SSG Landers, whose
   display equals its code, and "KTWIZ" for every team whose does not. */
.team-name .tn-code { display: none; }
/* THE NAME AND THE WIDTH SWITCH AT DIFFERENT POINTS, and that is the fix rather
   than an oversight. Both used to sit at 767.98px, which left 768-992px showing
   the long display name in a cell that cannot hold it plus a wild-card chip:
   "Chicago Cubs" measures 96px and the chip 27px against 117px of content box,
   so the chip dropped to a second line and the row stood 64px against 40px for
   every row without one. The code needs 29px there, which fits with room to
   spare. The 8% width below stays a PHONE rule -- it is tuned for a viewport
   with no surplus to redistribute, and applying it up here would undo the gain. */
@media (max-width: 991.98px) {
  .team-name .tn-display { display: none; }
  .team-name .tn-code { display: inline; }
}
@media (max-width: 767.98px) {
  /* WIDTH FOLLOWS THE CONTENT. Above this breakpoint the cell holds a short
     name ("Tampa Bay", and a full name for the six MLB teams that share a
     city), so 14% is earned. Below it the cell is three letters and a possible
     wild-card badge, and 14% rendered as 142px to draw "DET" -- four times what
     it needs, taken out of the columns the reader came for.

     8%, not the 7% floor: MLB's wild-card badge rows clip at 6%, so this is one
     clear step above the measured failure rather than sitting on its edge. */
  .table-auto th.col-team, .table-auto td.col-team { width: 8%; }
}

.team-record {
  font-size: 15px;
  color: gray;
  font-weight: 100;
}



/* ABOUT — three-tier team cards (skew/diagonal cards retired 2026-07-05).
   Brand accent stripe on top of every card; circular photos handle the
   mixed headshot aspect ratios via object-fit. */
.team-card {
  position: relative;
  border-top: 4px solid var(--riot-blue);
  padding: 1.4rem 1.1rem 1.2rem;
  text-align: center;
}
.tc-avatar {
  width: 110px;
  height: 110px;
  border-radius: 50%;
  object-fit: cover;
  object-position: center top;
  background: #f0f2f6;
  display: block;
  margin: 0 auto .85rem;
}
.tc-name {
  font-size: 18px;
  font-weight: 700;
  color: #212529;
}
.tc-role {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--riot-blue);
  margin: .15rem 0 .4rem;
}
.tc-edu {
  font-size: 14px;
  color: #6c757d;
  line-height: 1.45;
}
/* pinned to the top-right corner (just under the brand stripe) to reclaim the
   vertical space the old bottom link row took on every card */
.tc-links {
  position: absolute;
  top: .5rem;
  right: .6rem;
  display: flex;
  gap: .35rem;
  z-index: 2;
}
.tc-links a {
  display: inline-flex;
  opacity: .7;
  transition: opacity .1s ease;
}
.tc-links a:hover {
  opacity: 1;
}
/* faculty: bigger horizontal card, photo left */
.faculty-card {
  flex-direction: row;
  align-items: center;
  text-align: left;
}
.faculty-card .tc-avatar {
  flex-shrink: 0;
  margin: 0 1.1rem 0 0;
}
.faculty-card .tc-name {
  font-size: 20px;
}
/* alumni: compact grid card */
.alumni-card {
  padding: 1.1rem .8rem 1rem;
}
.alumni-card .tc-avatar {
  width: 84px;
  height: 84px;
}
.alumni-card .tc-name {
  font-size: 15px;
}
.alumni-card .tc-role {
  font-size: 12px;
}
.alumni-card .tc-edu {
  font-size: 13px;
}



/* METHODOLOGY PROSE — centered readable column, jump-link TOC, card accordion
   rows. Was the /faq page; /about renders the same faq_partials/* now, in both
   the global and the per-league shape. */
.faq-wrap {
  max-width: 56rem;
  margin: 0 auto;
}
/* "About RIOT Sports and the team ->", the per-league page's way back to the
   global one: a league page stops before the twelve bios rather than repeating
   them four times. */
.about-more {
  display: inline-block;
  margin-top: 1.4rem;
  font-size: 14px;
  font-weight: 600;
  color: var(--riot-blue);
  text-decoration: none;
}
.about-more:hover {
  text-decoration: underline;
}
/* The team is a section of /about now, not its own page, so its heading sits a
   level below the page title instead of competing with it. */
.about-team-head {
  font-size: 20px;
  letter-spacing: .06em;
  text-transform: uppercase;
  margin-top: 2.5rem;
}
.faq-toc {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .45rem;
  margin-bottom: 2rem;
}
.faq-toc a {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: #6c757d;
  text-decoration: none;
  padding: .3rem .85rem;
  border: 1px solid #e3e7ef;
  border-radius: 999px;
}
.faq-toc a:hover {
  color: var(--riot-blue);
  border-color: var(--riot-blue);
}
.faq-section {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--riot-blue);
  text-align: left;
  margin: 2.1rem 0 .9rem;
  padding-bottom: .4rem;
  border-bottom: 2px solid #eef1f6;
  scroll-margin-top: 90px; /* clears the sticky nav on jump-link click */
}

/* card row: question button + collapsible panel */
.faq-item {
  border: 1px solid #e3e7ef;
  border-radius: 8px;
  margin-bottom: .6rem;
  overflow: hidden;
  background: #fff;
}
.accordion {
  background-color: #fff;
  color: #212529;
  cursor: pointer;
  padding: 15px 46px 15px 18px; /* right room for the chevron */
  width: 100%;
  text-align: left;
  border: none;
  outline: none;
  position: relative;
  font-size: 16px;
  font-weight: 600;
  transition: background-color .1s linear, color .1s linear;
}
.accordion:hover { background-color: #f5f7fb; color: var(--riot-blue); }
.accordion:focus { outline: none; }
.accordion.active { background-color: #f0f3fa; color: var(--riot-blue); }
.accordion::after { /* chevron */
  content: "";
  position: absolute;
  right: 20px;
  top: 50%;
  width: 9px;
  height: 9px;
  border-right: 2px solid #9aa1ab;
  border-bottom: 2px solid #9aa1ab;
  transform: translateY(-70%) rotate(45deg);
  transition: transform .15s ease, border-color .15s ease;
}
.accordion.active::after {
  border-color: var(--riot-blue);
  transform: translateY(-30%) rotate(-135deg);
}

.panel {
  padding: 0 18px;
  background-color: #fff;
  display: none;
  overflow: hidden;
  border-top: 1px solid #eef1f6;
}
.panel .answer,
.panel ul.answer,
.panel ol.answer {
  font-size: 15px;
  color: #444;
  line-height: 1.6;
  margin: .85rem 0;
}
.panel h6 {
  font-weight: 700;
  color: #212529;
  margin: 1rem 0 .3rem;
}
/* worked-example table stays readable and scrolls on narrow screens */
.faq-table-wrap {
  overflow-x: auto;
  margin: .85rem 0;
}
table.faq-example {
  border-collapse: collapse;
  font-size: 14px;
  color: #333;
}
table.faq-example td {
  padding: 4px 10px;
}
/* League FAQ modal body: keep the shared card rows tidy inside the dialog */
.faq-modal .modal-body {
  padding: 1rem 1.25rem 1.25rem;
}
.faq-modal .faq-section {
  margin-top: 1.4rem;
}
.faq-modal .faq-section:first-child {
  margin-top: .2rem;
}



/* POPUP/MODAL STYLING */
/* Scenario popups put loose text/tables straight in .modal-content (no .modal-body),
   so add readable padding; .rounded-0 scopes it to the scenario/FAQ modals only. */
.modal-content.rounded-0 {
  padding: 0 1.25rem 1.1rem;
}
.modal-content.rounded-0 .modal-header {
  padding-left: 0;
  padding-right: 0;
  margin-bottom: .85rem;
}

/* button */
.close {
  color: black;
  opacity: 1;
}

.clickable {
  color: #2f5496; /* purp: #8c5ebd */
}



/* win or loss */
.win {
  color: #00B050;
  font-size: 16px;
  font-weight: 600;
}

.loss {
  color: #C00000;
  font-size: 16px;
  font-weight: 600;
}
/* Circle for more information section */

.circle{
  border:1px solid #000;
  width:20px;
  height:20px;
  border-radius:100%;
  position:relative;
  margin:4px;
  display:inline-block;
  vertical-align:middle;
  background-color: gray;

}
.circle.plus:before,
.circle.plus:after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background:#2f5496;
}
.circle.plus:before{
    width: 2px;
    margin: 2px auto;
}
.circle.plus:after{
    margin: auto 2px;
    height: 2px;
}
.circle.minus:before{
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background:#2f5496;
    margin: auto 2px;
    height: 2px;
}

/* SEEDING FOR WNBA AND NBA */
  .seed {
    display: inline-block;
    width: 2ch;              /* reserves 2 “typing spaces” */
    text-align: right;       /* makes 1 show like " 1" */
    margin-right: 0.4rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
                 "Liberation Mono", "Courier New", monospace;
  }

  .team-cell {
    display: flex;
    align-items: center;
  }

/* SECTION CAPTION — small muted eyebrow label above card groups */
.section-label {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #8a8f98;
}

/* home: quiet text link under the league cards to the standings preview */
.section-link {
  font-size: 15px;
  font-weight: 600;
  color: var(--riot-blue);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.section-link:hover {
  color: var(--riot-blue);
  border-bottom-color: var(--riot-blue);
  text-decoration: none;
}

/* standings: per-table conference/division sub-heading, smaller than the page
   title so the spelled-out league name reads as the dominant heading */
.standings-subhead {
  font-size: 20px;
  font-weight: 700;
  color: #495057;
}

/* HOME PAGE LEAGUE CARDS */
.league-card {
  transition: transform .1s ease, box-shadow .1s ease;
}
.league-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0,0,0,.15);
}
.league-card .card-title {
  color: #2f5496;
  font-weight: 700;
}
.league-card-link {
  color: #2f5496;
  font-size: 24px;
  font-weight: 700;
  text-decoration: none;
}
.league-card-link:hover {
  color: #2f5496;
  text-decoration: none;
}
.league-card-sub,
.league-card-sub a {
  font-size: 15px;
  color: #6c757d;
}
.league-card-sub a:hover {
  color: #2f5496;
}

/* HOME MODEL CARDS — magic-number explainers */
.mn-badge {
  display: inline-block;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .06em;
  color: var(--riot-blue);
  background: #eef2f9;
  border: 1px solid #d7e0ef;
  border-radius: 4px;
  padding: 2px 8px;
}

/* Two-line card caption: the "what" sentence, then the model-code chips */
.card-lead {
  font-size: 15px;
  color: #555;
  margin-bottom: .55rem;
}
.mn-codes {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .4rem 1rem;
  margin-bottom: 1rem;
}
.mn-code-pair {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: 14px;
  color: #555;
}
/* distinct monospace chip so the three-letter codes read as codes */
.mn-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  color: var(--riot-blue);
  background: #eef2f9;
  border: 1px solid #d7e0ef;
  border-radius: 4px;
  padding: 2px 7px;
}
/* kept blue (not the out/red treatment) for now: committing to red here reads
   as committing to it everywhere, and the rest of the home page is still blue */
.mn-code--elim {
  color: var(--riot-blue);
  background: #eef2f9;
  border-color: #d7e0ef;
}

/* mini standings snippet: rank + name bar rows, variant classes highlight one row */
.mini-standings {
  padding: .6rem .9rem;
  background: #fafbfd;
  border-top: 1px solid #eee;
  border-bottom: 1px solid #eee;
}
.ms-row {
  display: flex;
  align-items: center;
  padding: .28rem .5rem;
  border-radius: 4px;
}
.ms-rank {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 12px;
  color: #9aa1ab;
  width: 1.4rem;
  flex-shrink: 0;
}
.ms-bar {
  height: 8px;
  border-radius: 4px;
  background: #d8dce3;
}
.ms-row:nth-child(1) .ms-bar { width: 78%; }
.ms-row:nth-child(2) .ms-bar { width: 64%; }
.ms-row:nth-child(3) .ms-bar { width: 70%; }
.ms-row:nth-child(4) .ms-bar { width: 58%; }
.ms-row:nth-child(5) .ms-bar { width: 62%; }
.ms-cutoff {
  border-bottom: 2px dashed #b8bfc9;
  margin: .2rem .5rem;
}
/* Highlighted example rows all read as one riot-blue tone (no green/amber/red) --
   matches the standings table and the vg-* glyphs, which dropped severity coloring
   for a single consistent brand color. */
.ms-row.ms-secured,
.ms-row.ms-caution,
.ms-row.ms-out { background: #eaf0f8; }
.ms-row.ms-secured .ms-bar,
.ms-row.ms-caution .ms-bar,
.ms-row.ms-out .ms-bar { background: var(--riot-blue); }
.ms-row.ms-secured .ms-rank,
.ms-row.ms-caution .ms-rank,
.ms-row.ms-out .ms-rank { color: var(--riot-blue); font-weight: 700; }
.ms-row.ms-locked .ms-bar { background: #aab2bd; }

/* VALUE VOCABULARY ROWS — inside the home model cards */
.model-vocab {
  text-align: left;
  border-top: 1px solid #eee;
  padding-top: .75rem;
  margin-top: .25rem;
}
.model-vocab .value-glyph {
  font-size: 20px;
  min-width: 3.4rem;
}
.model-vocab .vg-in,
.model-vocab .vg-elim {
  font-size: 16px;
}
.value-row {
  display: flex;
  align-items: baseline;
  margin-bottom: .55rem;
}
.value-glyph {
  font-size: 26px;
  font-weight: 700;
  min-width: 3.4rem;
  text-align: right;
  margin-right: .9rem;
  font-variant-numeric: tabular-nums;
}
/* All state glyphs render riot-blue to match the standings table, where
   green/red/amber state coloring was turned off for a uniform plain-text
   look. The
   moot em-dash stays muted gray (a "not applicable" state, not a real value). */
.vg-number { color: var(--riot-blue); }
.vg-star { color: var(--riot-blue); }
.vg-in { color: var(--riot-blue); font-size: 20px; }
.vg-elim { color: var(--riot-blue); font-size: 20px; }
.vg-moot { color: var(--riot-blue); }
.value-text {
  font-size: 15px;
  color: #555;
}
.value-note {
  font-size: 13px;
  color: #777;
  border-top: 1px solid #eee;
  padding-top: .75rem;
  margin-top: .75rem;
  line-height: 1.5;
}

/* STANDINGS LEAGUE PILL BAR — navigation */
.league-pill-bar {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: .5rem;
}
.league-pill {
  display: inline-block;
  padding: .55rem 1.9rem;
  border-radius: 999px;
  border: 1px solid #cfd6e4;
  color: var(--riot-blue);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: .04em;
  background: #fff;
  text-decoration: none;
  transition: background .12s ease, color .12s ease;
}
.league-pill:hover {
  background: #eef2f9;
  color: var(--riot-blue);
  text-decoration: none;
}
.league-pill.active {
  background: var(--riot-blue);
  border-color: var(--riot-blue);
  color: #fff;
}
/* Sub-view = a connected segmented control (one setting, N values). It is no
   longer navigation: every group's table is on the page and the control focuses
   one client-side (static/js/standings-view.js), so `.active` is set by the
   script after the first paint, not by the template alone. League navigation is
   the header's tier-1 tabs. */
.league-segbar {
  display: flex;
  width: fit-content;
  margin: .7rem auto 0;
  border: 1px solid #cfd6e4;
  border-radius: 8px;
  overflow: hidden;
}
.league-seg {
  padding: .28rem 1.2rem;
  font-size: 14px;
  font-weight: 600;
  color: #6c757d;
  background: #fff;
  text-decoration: none;
  border-left: 1px solid #cfd6e4;
}
.league-seg:first-child {
  border-left: none;
}
.league-seg:hover {
  background: #eef2f9;
  color: var(--riot-blue);
  text-decoration: none;
}
.league-seg.active {
  background: var(--riot-blue);
  color: #fff;
}

/* STANDINGS MODEL-KEY STRIP — quiet reminder labels, not navigation */
.mn-key {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .4rem .6rem;
  margin: .5rem 0 1rem;
}
.mn-key-item {
  display: inline-flex;
  align-items: baseline;
  gap: .4rem;
  border: 1px solid #e3e7ee;
  border-radius: 6px;
  background: #f8f9fc;
  padding: .25rem .6rem;
  cursor: default;
}
.mn-key-abbr {
  font-weight: 700;
  font-size: 13px;
  color: var(--riot-blue);
}
.mn-key-label {
  font-size: 13px;
  color: #6c757d;
}

/* HOME — league preview cards (the standings preview absorbed the thin league
   card in B5, so these render on home; bare /standings redirects there) */
.preview-card {
  text-align: left;
}
.preview-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: .7rem 1rem;
  border-bottom: 1px solid #e9ecf2;
}
.preview-league {
  font-size: 18px;
  font-weight: 700;
  color: var(--riot-blue);
  text-decoration: none;
}
.preview-league:hover {
  color: var(--riot-blue);
}
.preview-status {
  font-size: 12px;
  color: #8a8f98;
}
/* sub-view chips (East/West, AL/NL) — the links the thin home card carried,
   folded into the merged card so the merge costs no link */
.preview-chips {
  display: flex;
  gap: .4rem;
  padding: .5rem 1rem 0;
}
.preview-chip {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .02em;
  line-height: 1.5;
  color: #6c757d;
  background: #f3f5f9;
  border: 1px solid #e4e8f0;
  border-radius: 999px;
  padding: 0 7px;
  text-decoration: none;
}
.preview-chip:hover {
  color: var(--riot-blue);
  border-color: #c9d4e8;
  text-decoration: none;
}
.preview-row {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .55rem 1rem;
  border-bottom: 1px solid #f0f2f6;
}
.preview-rank {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 12px;
  color: #9aa1ab;
  width: 1rem;
  flex-shrink: 0;
}
.preview-name {
  flex: 1;
  font-size: 14px;
  font-weight: 600;
  color: #212529;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.preview-mn {
  display: flex;
  align-items: baseline;
  gap: .35rem;
  flex-shrink: 0;
}
.preview-mn-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: #9aa1ab;
}
.preview-mn-value {
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.pv-number { color: var(--riot-blue); }
.pv-caution { color: var(--caution-accent); }
.pv-moot { color: var(--moot-gray); }
.pv-secured {
  color: var(--secured-text);
  background: var(--secured-bg);
  border-radius: 999px;
  padding: 1px 9px;
  font-size: 12px;
}
.pv-out {
  color: var(--out-text);
  background: var(--out-bg);
  border-radius: 999px;
  padding: 1px 9px;
  font-size: 12px;
}
.preview-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: .6rem 1rem;
  background: #fafbfd;
}
.preview-foot a {
  font-size: 13px;
  font-weight: 600;
  color: var(--riot-blue);
}
.preview-foot .preview-status {
  font-size: 11px;
}

/* TABLE KEY — one band for the page, below the last table: stat keys left,
   As-of/Final right, one row spread apart. No border: it is its own row now,
   not a footer seated on a card, so there is no edge above it to answer to. */
.table-key {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: .3rem 1rem;
  padding: .6rem .9rem;
}
.tk-keys {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: .3rem 1rem;
}
.tk-item {
  font-size: 14px;
  color: #8a8f98;
  white-space: nowrap;
}
.tk-item b {
  color: #495057;
}
.tk-asof {
  font-size: 15px;
  font-weight: 600;
  color: #6c757d;
  white-space: nowrap;
}

/* MAGIC-NUMBER CELLS — emitted by the mn_cell tag (custom_tags.py).
   nowrap: no label may ever wrap a row taller (the "In playoffs" bug).
   State colors mirror the home model-card glyphs (.vg-*): word = tier,
   color = severity; red only when the postseason door is fully closed. */
.mn-cell {
  white-space: nowrap;
}
.mn-cell .info_button {
  font-variant-numeric: tabular-nums;
  font-weight: 700; /* bold magic-number values: a clean bold look */
}
/* No cell coloring for now (2026-07-06, for a clean plain-text look). The
   mn-{state} class stays on the <td> as a hook for the future zone/pill styling
   (see *Standings cell color* plan section), but renders no color today. */

/* SEASON STATUS — muted progress line (league page heading, home cards) */
.season-status {
  font-size: 15px;
  color: #8a8f98;
  letter-spacing: .02em;
}
.league-card-status {
  font-size: 13px;
  color: #8a8f98;
  margin-top: .25rem;
}

/* FOOTER — brand block + link columns */
.footer-brand {
  font-size: 20px;
  font-weight: 800;
  color: var(--riot-blue);
}
.footer-tagline {
  font-size: 14px;
  color: #8a8f98;
}
.footer-col {
  text-align: left;
}
.footer-col-label {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #8a8f98;
  margin-bottom: .35rem;
}
.footer-col a {
  display: block;
  font-size: 15px;
  color: #6c757d;
  text-decoration: none;
  padding: 2px 0;
}
.footer-col a:hover {
  color: var(--riot-blue);
  text-decoration: none;
}

/* STANDINGS TABLE — ONE width system (2026-07-06):
   (1) the card caps the width and centers, so zooming out adds margin, not
       stretch (matches the inspo, table never changes size past the cap);
   (2) table-layout: fixed with proportional column widths, so columns scale
       together and the browser never redistributes surplus unevenly;
   (3) below min-width the .table-responsive wrapper scrolls (never wrap).
   Stop hand-tuning individual column px after this — set the cap + the
   proportions, done. */
.standings-card {
  width: 100%;
  max-width: 1040px;
}
/* 800px, and it is a measured number. Fixed layout hands every column a share
   of THIS width, so it is the budget the content has to fit in: at 680 the
   widest label RIOT prints, "Clinched", got 71px and needed 93, and a
   two-digit rank got 33 and needed 37. Both clipped, on a phone, silently.
   780 is the floor where everything fits across all four leagues at 320-390;
   this is one step above it. The table already scrolls sideways in
   .table-responsive, so the cost is a little more scrolling and the benefit is
   that no cell lies. */
.table-auto {
  width: 100%;
  min-width: 800px;
  table-layout: fixed;
  margin: 0 auto;
}
.table-auto th,
.table-auto td {
  padding: 0.4rem 0.55rem;
  vertical-align: middle;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Numbers are compared DOWN a column, so they get tabular figures: a 1 takes
   the width of a 7 and the digits line up, which is most of what makes a
   standings table readable at a glance rather than a list of numerals. */
.table-auto .col-stat,
.table-auto .rank-col,
.table-auto td.mn-cell {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}
.table-auto thead th {
  vertical-align: bottom;
  border-bottom: 1px solid #e9ecf2;
}
.table-auto .team-name {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
}
/* Proportional column widths. Fixed layout scales these ratios to fill the
   table, so they hold at any width and across leagues (varying column counts):
   Team widest, model columns equal medium, stat columns narrow, rank tiny. */
.col-team {
  width: 14%;
  text-align: left;
}
.col-stat {
  width: 6%;
  text-align: center;
}
/* THE ONE FIVE-CHARACTER COLUMN, AND IT MUST STAY BELOW .col-stat. Every other
   stat is at most three digits and fits the 6% above; "0.586" does not, and was
   being cut to "0...." by the ellipsis further down -- the column that says how
   good a team is, showing nothing at all. The cell carries both classes, so
   whichever rule is written LAST wins: above .col-stat this was dead CSS that
   read as a fix. Do not sort this block alphabetically. */
.pct-col {
  width: 9%;
}
.table-auto th.mn-col,
.table-auto td.mn-cell {
  width: 8%;
  text-align: center;
}
.rank-col {
  width: 4%;
  text-align: center;
}
.table-auto tbody .rank-col {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  color: #9aa1ab;
  font-weight: 600;
}


/* ================= Session B2: canonical explanations + zones ============= */

/* EXPLANATION BLOCKS — the labeled state / what's-needed / evidence standard
   shared by popups (short form) and scenario pages (long form). */
.exp-blocks {
  font-size: 15px;
  line-height: 1.45;
}
.exp-page {
  max-width: 860px;
  margin: 0 auto 1.5rem;
  padding: 0 1rem;
}
.exp-title {
  font-size: 26px;
  margin-bottom: 1rem;
}
/* scenario-page header, prose form (v4): plain paragraphs, no label column */
.scn-lead {
  font-size: 16px;
  line-height: 1.5;
}
.scn-lead > p { margin-bottom: .7rem; }
.scn-lead .exp-table { max-width: 520px; margin: .2rem 0 .9rem; }
.exp-block {
  display: flex;
  align-items: baseline;
  gap: .75rem;
  padding: .45rem 0;
  border-top: 1px solid #eef1f6;
}
.exp-block:first-child { border-top: 0; }
.exp-label {
  flex: 0 0 7.5rem;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #8a8f98;
}
.exp-text { flex: 1 1 auto; min-width: 0; }

/* MOBILE — the label goes ABOVE its content, not beside it. `7.5rem` is a
   third of a 375px screen, and it is spent on one word: the prose beside it
   wrapped every four or five words, and the final-standings table lost the
   room it needed before the phone had run out of any. Same blocks, stacked. */
@media (max-width: 720px) {
  .exp-block {
    display: block;
    padding: .6rem 0;
  }
  .exp-label {
    display: block;
    margin-bottom: .2rem;
  }
}
.exp-text p { margin-bottom: .4rem; }
.exp-text p:last-child { margin-bottom: 0; }
.exp-tie { }
.exp-ties { margin: 0 0 .3rem 1.1rem; padding: 0; }
.exp-ties li { margin-bottom: .25rem; }
.exp-more { color: #8a8f98; font-style: italic; }
.wit-label { font-weight: 700; margin: .4rem 0 .15rem; }
.wit-cut > td { border-bottom: 2px solid rgba(0, 0, 0, 0.25); }
.exp-table {
  width: 100%;
  margin: .35rem 0;
  font-variant-numeric: tabular-nums;
  border-collapse: collapse;
}
.exp-table th, .exp-table td {
  padding: .2rem .5rem;
  text-align: center;
  border-bottom: 1px solid #eef1f6;
}
.exp-table th:first-child, .exp-table td:first-child { text-align: left; }
.exp-foot {
  margin-top: .65rem;
  padding-top: .55rem;
  border-top: 1px solid #eef1f6;
  font-size: 14px;
}
/* popups (words-first, v3): a line or two of prose, then the witness table.
   Cap the height so a tall witness scrolls inside the modal. */
.pop-body {
  font-size: 15px;
  line-height: 1.45;
  max-height: 62vh;
  overflow-y: auto;
}
.pop-note p { margin-bottom: .5rem; }
.pop-body .exp-table { margin-top: .25rem; }

/* CUTLINES: the qualifying-boundary separators (today's ordering, never a
   clinch/elim claim). Row tints and the legend were tried and dropped
   (2026-07-18, as off-brand); word cells stay plain bold text. */
.zone-sep > td, .zone-sep > th { border-top: 2px solid rgba(0, 0, 0, 0.25); }

/* MLB wild-card slot chips (WC1/WC2/WC3, computed at view time) */
.slot-badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  padding: 1px 4px;
  border-radius: 8px;
  background: #eef1f6;
  color: #2f5496;
  white-space: nowrap;
  /* Both of these are measured, not chosen. The team cell is 83px on a phone
     whatever the viewport, because the table scrolls rather than reflows, so
     there is exactly ONE width to satisfy: code (29px) + gap + chip has 4.5px
     of room at 1px 4px and .25rem, and none at the 1px 6px / .35rem it was --
     which is why every wild-card row was 64px tall against 40px for the rest. */
  margin-left: .25rem;
  vertical-align: middle;
}
/* MLB wild-card legend line under the magic-number key */
.wc-key {
  max-width: 620px;
  margin: .5rem auto 0;
  font-size: 13px;
  color: #6c757d;
  text-align: center;
  line-height: 1.4;
}
.wc-key .slot-badge { margin: 0 .1rem; }

/* SEASON-END RECAP — the Final-result column (D2/S8) */
.final-col {
  width: 22%;
  text-align: left;
  font-weight: 600;
}

/* SCENARIO PAGES: one capped column; wide tables scroll inside it */
.scn-body {
  max-width: 860px;
  margin: 0 auto 1.5rem;
  padding: 0 1rem;
}
.scn-body table.display { width: 100% !important; }
.scn-body .dataTables_wrapper { overflow-x: auto; }

/* SCENARIO PAGES — section heads + collapsed head-to-head summary */
.scn-head { margin: 1.4rem 0 .3rem; }
.scn-subhead { margin: .9rem 0 .3rem; }
.witness-note {
  color: #6c757d;
  font-size: 14px;
  margin-bottom: .6rem;
}
.h2h-details { margin: 1.2rem 0; }
.h2h-details > summary {
  cursor: pointer;
  font-size: 18px;
  font-weight: 700;
  color: var(--riot-blue);
  padding: .35rem 0;
}
.hl-row > td, .hl-row > th { background: rgba(47, 84, 150, 0.08); }
td.hl-col { background: rgba(47, 84, 150, 0.08); }

/* The cells a decisive-tie note is about. Fill is already spent on the page
   team's row and column, and text color is the series result, so the tiebreak
   gets the one channel left: outline. Solid where the season series settled
   the tie, dashed where it is the cell that FAILED to (06). */
td.tie-key { outline: 2px solid var(--riot-blue); outline-offset: -2px; }
td.tie-open { outline: 1px dashed rgba(47, 84, 150, 0.55); outline-offset: -1px; }
tr.tie-key > td { box-shadow: inset 0 2px 0 var(--riot-blue), inset 0 -2px 0 var(--riot-blue); }
tr.tie-open > td { box-shadow: inset 0 1px 0 rgba(47, 84, 150, 0.4), inset 0 -1px 0 rgba(47, 84, 150, 0.4); }

/* MOBILE — the standings table always overflows a phone viewport (NBA renders
   14 columns; the table's own min-width is 680px), so the wrapper scrolls
   horizontally and the team identity column stays pinned (B2 phone-width
   check, 2026-07-18). Background required: a sticky cell is transparent by
   default and rows would show through it while scrolling. */
@media (max-width: 720px) {
  /* ONE FROZEN COLUMN, PINNED AT THE EDGE. Freezing the rank as well needs the
     team column offset by the rank's rendered width, and that width is not a
     constant: `table-layout: fixed` gives each column its percentage of a
     680px min-width PLUS a share of whatever surplus the viewport has, so the
     offset drifts with the screen and the gap between the two frozen cells
     shows the scrolling table through it. A magic number cannot track that.
     So the team column alone freezes, at left 0, where no arithmetic can be
     wrong. The rank slides under it, which costs a number that is 1-15 and
     visible again the moment you scroll back. */
  .table-auto th.col-team, .table-auto td.col-team {
    position: sticky;
    left: 0;
    z-index: 2;
    background: #fff;
    /* THE EDGE IS THE POINT. Without it the scrolled columns slide under the
       frozen pair with nothing between them, and the row reads as broken text
       -- "offs (2 seed)", "n the Eastern Conference". The shadow says the
       column is on top of something rather than cut off. */
    box-shadow: 6px 0 7px -5px rgba(15, 30, 60, 0.35);
  }
}

/* The head-to-head summary is a square matrix: 15 columns for an NBA
   conference, every cell a score like "2 - 2". DataTables sizes a table to
   100% of its container, so at that width the cells wrapped onto a second line
   and the row grew. A score must never break across lines, so the cells refuse
   to wrap, the table takes whatever width it needs, and the wrapper scrolls
   sideways instead. */
.scn-body table.display th,
.scn-body table.display td {
  white-space: nowrap;
}
.scn-body table.display {
  width: auto !important;
  min-width: 100%;
}

/* Column legend ('i' popup). It reuses .exp-table, which centers every column
   after the first -- right for a table of numbers, wrong for a table of
   sentences, so the legend left-aligns its prose column back. */
.legend-table {
  width: 100%;
  margin-bottom: 0.4rem;
}
.legend-table th,
.legend-table td {
  text-align: left;
  white-space: normal;
  vertical-align: top;
}
.legend-code {
  font-weight: 700;
  white-space: nowrap;
  width: 4.5rem;
}
.legend-table th:nth-child(2),
.legend-table td:nth-child(2) {
  width: 12rem;
}
.legend-head {
  margin: 1.2rem 0 0.4rem;
  font-weight: 700;
  font-size: 0.95rem;
}
.legend-foot {
  font-size: 0.9rem;
  color: #6b727c;
  margin-top: 0.9rem;
}
.legend-modal .modal-body {
  padding-top: 0.6rem;
}

/* The traditional magic number is context, not the claim, so it sits back;
   the evidence intro leads straight into its table. */
.pop-trad {
  color: #6b727c;
  font-size: 0.9rem;
}
.pop-intro {
  margin-bottom: 0.3rem;
}

/* SEASON STATE ------------------------------------------------------------
   Replaced "Game 73 of 82" on the cards and the standings heading: that was a
   league-wide average, never any real team's game count. What the slot carries
   now is whether the numbers can still move.

   STATUS CHIP, harvested from webpage_new (2026-08-12) — this supersedes the
   earlier dot-only badge, whose comment recorded "a filled pill was tried
   first and shouted": the mock is the newer call and the pill is back with
   it. Colors come from the existing severity tokens; no new palette.
   Live is the only state that earns motion. The mock also carried an unused
   `--final` variant; two states exist in the data, so two ship. */
.status-chip {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  border-radius: 999px;
  padding: .15rem .6rem;
  border: 1px solid transparent;
  white-space: nowrap;
  vertical-align: middle;
}
.status-chip--live {
  color: var(--secured-text);
  background: var(--secured-bg);
}
.status-chip--live::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--secured-accent);
  animation: riot-pulse 2.4s ease-in-out infinite;
}
/* A season that has FINISHED. Keeps the look this chip has always had -- it is
   the state that already shipped, and nothing about it changed. */
.status-chip--ended {
  color: var(--ink-muted);
  background: #fff;
  border-color: #dfe3ea;
}
/* A season that has NOT STARTED. Until foundation/12 §2 this shared `--off`
   with the state above, so "season complete" and "between seasons" were the
   same pill on a page whose whole job is to say which. The dot is the live
   chip's, hollow and still: something is coming, nothing is happening. */
.status-chip--off {
  color: var(--ink-muted);
  background: var(--rule-soft);
  border-color: #dfe3ea;
}
.status-chip--off::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  border: 1px solid currentColor;
}
@keyframes riot-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: .35; }
}
@media (prefers-reduced-motion: reduce) {
  .status-chip--live::before { animation: none; }
}

/* On the standings page the chip sits in a row with the "who advances" note.
   align-items is CENTER, not baseline, and that is load-bearing
   (2026-07-29, when the chip visibly failed to line up): the live chip is a
   flex container
   whose first flex item is the empty 6px dot pseudo-element, so under
   `baseline` the parent synthesizes the chip's baseline from that dot's box
   rather than from the word "Live", pushing the text off the note's baseline. */
.season-line {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  font-size: 15px;
  color: #8a8f98;
  letter-spacing: .02em;
}
.season-sep {
  color: #c3c8d0;
}

/* Says the league has not finished publishing its schedule (the NBA's
   Cup-displaced December games). Quieter than the season line above it: it is a
   caveat on the numbers, not a fact about the season. */
.schedule-note {
  display: inline-block;
  max-width: 44rem;
  font-size: 13px;
  line-height: 1.5;
  color: #8a8f98;
}

/* season-ended banner + countdown (webpage_new harvest) */
.season-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: .3rem .9rem;
  max-width: 1040px;
  margin: 0 auto 1rem;
  padding: .7rem 1rem;
  background: var(--rule-soft);
  border: 1px solid var(--rule);
  border-radius: 6px;
  text-align: center;
}
.season-banner-main {
  font-size: 15px;
  font-weight: 700;
  color: var(--ink-soft);
}
.season-banner-sub {
  font-size: 14px;
  color: var(--ink-muted);
}
.season-countdown {
  font-weight: 700;
  color: var(--riot-blue);
  font-variant-numeric: tabular-nums;
}

/* All four preview-card footers must be the same height whether or not the card
   has sub-view chips (2026-07-29: the NBA/MLB footers were taller than
   WNBA/KBO's). Two causes, both fixed here: .preview-chips carries its own
   `padding: .5rem 1rem 0` from the header position it used to occupy, which was
   still adding half a rem inside the footer band; and nothing pinned the band's
   height, so it was set by whichever child happened to be tallest.

   min-height 2.4rem = 38.4px against .6rem*2 padding (19.2px), which comfortably
   clears the tallest child (a chip is 10px x 1.4 line-height + 2px border = 16px),
   so every footer resolves to the same height instead of tracking its contents. */
.preview-foot {
  min-height: 2.4rem;
}
.preview-foot .preview-chips {
  display: inline-flex;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
}
.preview-foot .preview-chip {
  font-size: 10px;
  line-height: 1.4;
  padding: 0 6px;
}

/* DORMANT LEAGUE (webpage_new harvest, 2026-08-12) — a finished season grays
   out rather than disappears: the final numbers stay readable, but nothing on
   the surface claims they can still move. Card variant for home/landing,
   .season-dormant wrapper for the league standings page. */
.preview-card--dormant {
  background: #e9ebef;
}
.preview-card--dormant .preview-league { color: var(--ink-muted); }
.preview-card--dormant .gate-link { color: #7c93bc; }
.preview-card--dormant .preview-name {
  color: var(--ink-muted);
  font-weight: 500;
}
.preview-card--dormant .preview-rank,
.preview-card--dormant .preview-mn-label { color: #c2c8d2; }
.preview-card--dormant .preview-mn-value { color: var(--moot-gray); }
.preview-card--dormant .pv-secured {
  color: var(--ink-muted);
  background: #edeff2;
}
.preview-card--dormant .preview-foot { background: #e9ebef; }
.preview-card--dormant .preview-row { border-bottom: none; }

/* league page: same idea applied to the table */
.season-dormant .standings-subhead,
.season-dormant h2 { color: var(--ink-muted); }
.season-dormant .standings-card { background: #fafbfc !important; }
.season-dormant .table-auto .team-name { color: var(--ink-muted); }
.season-dormant .mn-cell .info_button,
.season-dormant .clickable { color: var(--ink-muted); }
.season-dormant .mn-key-abbr { color: var(--ink-muted); }
.season-dormant .table-auto tbody .rank-col { color: #c2c8d2; }

/* ABOUT — "How the numbers work" figure + term table (webpage_new harvest,
   2026-08-13). The butterfly reads outward from the center: left wing is the
   games-left budget, right wing the wins still required, both measured on the
   same track length so the pair compares directly. */
.section-intro {
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink-soft);
  max-width: 44rem;
  margin: 0 0 1.6rem;
}
.faq-subsection {
  font-size: 15px;
  font-weight: 700;
  color: var(--riot-blue);
  text-align: left;
  margin: 0 0 .8rem;
}
.butterfly {
  margin: 0 0 2.75rem;
}
.bf-head,
.bf-row {
  display: grid;
  grid-template-columns: 1fr 8.5rem 1fr 7.5rem;
  align-items: center;
  gap: .5rem;
}
.bf-head {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding-bottom: .45rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: .35rem;
}
.bf-head-left  { text-align: right; }
.bf-head-right { text-align: left; }
.bf-row {
  padding: .45rem 0;
}
.bf-side {
  display: flex;
  align-items: center;
  gap: .5rem;
  min-width: 0;
}
.bf-val {
  width: 2ch;
  flex-shrink: 0;
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
}
.bf-side--left .bf-val  { text-align: right; }
.bf-side--right .bf-val { text-align: left; }
.bf-track {
  flex: 1;
  display: flex;
  min-width: 0;
}
.bf-side--left .bf-track  { justify-content: flex-end; }
.bf-side--right .bf-track { justify-content: flex-start; }
.bf-bar {
  height: 14px;
  border-radius: 3px;
  flex-shrink: 0;
}
/* left wing is the budget, right wing the verdict — same hue, left the lighter
   tint, so the pair reads as one measurement instead of two colors */
.bf-row--alive .bf-bar--left  { background: var(--secured-bg); }
.bf-row--out   .bf-bar--left  { background: var(--out-bg); }
.bf-row--alive .bf-bar--right { background: var(--secured-accent); }
.bf-row--out   .bf-bar--right { background: var(--out-accent); }
.bf-team {
  text-align: center;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bf-verdict {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .04em;
  white-space: nowrap;
}
.bf-row--alive .bf-verdict { color: var(--secured-text); }
.bf-row--out   .bf-verdict { color: var(--out-text); }
.bf-key {
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-muted);
  margin: .9rem 0 0;
  padding-top: .8rem;
  border-top: 1px solid var(--rule-soft);
}
@media (max-width: 767.98px) {
  .bf-head,
  .bf-row { grid-template-columns: 1fr 5.5rem 1fr; }
  .bf-head-verdict { display: none; }
  .bf-verdict { grid-column: 1 / -1; text-align: center; padding-top: .1rem; }
  .bf-team { font-size: 13px; }
}

/* definition-of-terms quick reference */
.mn-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  color: var(--riot-blue);
  background: #eef2f9;
  border: 1px solid #d7e0ef;
  border-radius: 4px;
  padding: 2px 7px;
}
.term-table {
  border-top: 1px solid var(--rule-soft);
}
.term-row {
  display: flex;
  align-items: flex-start;
  gap: .9rem;
  padding: .85rem 0;
  border-bottom: 1px solid var(--rule-soft);
}
.term-row .mn-code {
  flex-shrink: 0;
  min-width: 3.1rem;
  text-align: center;
  margin-top: .15rem;
}
.term-body { min-width: 0; }
.term-name {
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
}
.term-desc {
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-soft);
  margin: .15rem 0 0;
}
.term-note {
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-muted);
  margin: 1rem 0 0;
}

/* EVENTS PAGE — the recorded clinch/elimination timeline (2026-08-13).
   One row per event, grouped under its date. Colour follows the severity
   tokens already in use for cells, so a clinch reads the same green here as
   in the standings table. */
.event-filters {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .6rem 1rem;
  padding-bottom: .9rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 1.2rem;
}
.event-filter-team {
  font-size: 14px;
  color: var(--ink-soft);
  border: 1px solid var(--rule);
  border-radius: 6px;
  padding: .25rem .5rem;
  background: #fff;
}
.event-type-chips, .event-tier-chips {
  display: inline-flex;
  gap: .35rem;
  flex-wrap: wrap;
}
/* Two chip rows, two independent filters. The tier row is outlined rather than
   filled when active, so a reader can see at a glance which of the two groups
   a selection belongs to. */
.event-chip {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--ink-muted);
  background: #fff;
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: .2rem .7rem;
  cursor: pointer;
}
.event-chip:hover { color: var(--riot-blue); }
.event-chip.active {
  color: #fff;
  background: var(--riot-blue);
  border-color: var(--riot-blue);
}
/* Tier and group chips read as a SECOND rank of filter, so their active state
   is outlined where the type chips are filled. Three solid pills in a row would
   say the three groups are the same kind of choice, and picking one from each
   is the normal case. */
.event-chip--tier.active,
.event-chip--group.active {
  color: var(--riot-blue);
  background: #fff;
  border-color: var(--riot-blue);
  box-shadow: inset 0 0 0 1px var(--riot-blue);
}
.event-day {
  margin-bottom: 1.6rem;
}
.event-date {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  text-align: left;
  margin: 0 0 .5rem;
}
.event-row {
  display: flex;
  align-items: baseline;
  gap: .7rem;
  padding: .55rem 0;
  border-bottom: 1px solid var(--rule-soft);
}
.event-badge {
  flex-shrink: 0;
  min-width: 6.5rem;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-align: center;
  border-radius: 999px;
  padding: .1rem .5rem;
  color: var(--ink-muted);
  background: var(--rule-soft);
}
.event-badge--clinch {
  color: var(--secured-text);
  background: var(--secured-bg);
}
.event-badge--elim {
  color: var(--out-text);
  background: var(--out-bg);
}
.event-badge--one_away_clinch {
  color: var(--caution-text);
  background: var(--caution-bg);
}
.event-text {
  flex: 1;
  font-size: 15px;
  color: var(--ink);
  min-width: 0;
}
.event-empty,
.event-empty-filtered {
  font-size: 15px;
  color: var(--ink-muted);
}
@media (max-width: 575.98px) {
  .event-row { flex-wrap: wrap; }
  .event-badge { min-width: 5.5rem; }
}

/* Postseason picture: a finish RIOT could not prove reads quieter than one it
   could. The cell already says less (a tier, no seed number) -- this stops the
   two kinds of answer looking equally certain sitting next to each other. */
.picture-table .picture-contested {
    color: #6c757d;
    font-style: italic;
}

/* POSTSEASON BRACKET ---------------------------------------------------------
   The rule, 2026-08-17: a team that has CLINCHED the seat is coloured in, and
   one merely sitting in it today is greyed out but still shown.

   Read as a CLAIM rule, not a palette. A bracket cannot decline to commit the
   way a table can -- putting a team in a slot says who it plays -- so the fill
   is what separates a fact from a snapshot:

     --proven   filled, RIOT can prove the team belongs in this round
     --current  greyed, this is only where the table sits today
     --tbd      outlined, nobody has won the seat yet (NBA 7/8 pre play-in)

   Every colour is an existing token. "Clinched" reuses the SAME secured tokens
   the magic-number cells use, so a filled seat and a `Clinched` cell are the
   one green on this site rather than two. */

.bracket {
  margin: 1.5rem 0 .5rem;
}

.bracket-group {
  margin-bottom: 2rem;
}

.bracket-group-name,
.bracket-feeder-name {
  color: var(--ink-muted);
  letter-spacing: .04em;
  text-transform: uppercase;
  margin-bottom: .6rem;
}

.bracket-round {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
}

.bracket-matchup {
  display: flex;
  align-items: center;
  gap: .4rem;
  flex: 1 1 15rem;
}

.bracket-versus {
  color: var(--ink-faint);
  font-size: 13px;
  flex: 0 0 auto;
}

.bracket-seat {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex: 1 1 auto;
  min-width: 0;
  padding: .45rem .6rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  font-size: 15px;
}

.bracket-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bracket-seed {
  flex: 0 0 1.4rem;
  text-align: center;
  font-size: 13px;
  color: var(--ink-muted);
}

/* No number: RIOT could not prove one against the team level with this one
   The dot holds the column so rows still line up. */
.bracket-seed--tied {
  color: var(--moot-gray);
  cursor: help;
}

.bracket-seat--proven {
  background: var(--secured-bg);
  border-color: var(--secured-accent);
  color: var(--secured-text);
}

.bracket-seat--proven .bracket-seed {
  color: var(--secured-accent);
}

.bracket-seat--current {
  background: var(--rule-soft);
  color: var(--ink-muted);
}

.bracket-seat--tbd {
  background: transparent;
  border-style: dashed;
  color: var(--ink-faint);
  font-style: italic;
}

/* A tie is the one thing a bracket's SHAPE cannot express -- the seat is drawn
   in one place and the two teams could swap -- so the seat itself is marked. */
.bracket-seat--tied {
  border-left-width: 3px;
  border-left-color: var(--moot-gray);
}

/* KBO climbs instead of branching: 4v5, winner plays 3, then 2, then 1.
   column-reverse so the first rung sits at the bottom and the Korean Series on
   top, which is the direction the ladder is actually climbed. */
.bracket-ladder {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column-reverse;
  gap: .5rem;
}

.bracket-step {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
}

.bracket-step-name {
  flex: 0 0 8.5rem;
  color: var(--ink-muted);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .04em;
}

.bracket-step-seats {
  display: flex;
  gap: .5rem;
  flex: 1 1 18rem;
  flex-wrap: wrap;
}

.bracket-feeder,
.bracket-byes {
  margin-top: 1rem;
}

.bracket-key {
  font-size: 13px;
}

.bracket-key-swatch {
  display: inline-block;
  width: .85rem;
  height: .85rem;
  vertical-align: -1px;
  border: 1px solid var(--rule);
  border-radius: 3px;
}

.bracket-key-swatch--proven {
  background: var(--secured-bg);
  border-color: var(--secured-accent);
}

.bracket-key-swatch--current {
  background: var(--rule-soft);
}

.bracket-key-swatch--tbd {
  border-style: dashed;
}

@media (max-width: 575px) {
  .bracket-matchup { flex: 1 1 100%; }
  .bracket-step-name { flex: 1 1 100%; }
}


/* ============================================================================
   HOME — LATEST INSIGHT CARD
   Harvested from webpage_new 2026-08-17. The signature piece is .mn-track: the
   ARC of a magic number moving toward its outcome, rather than just asserting
   the outcome. Built from vocabulary that already exists here -- .mn-code for
   the metric chip, .pv-secured / .pv-out for the terminal pill, --riot-blue for
   the track. NO NEW COLOR: the draft used three #fafbfd literals for the track
   background, and those are var(--rule-soft) here instead. That substitution is
   load-bearing, not cosmetic -- the connector mask below has to be the SAME
   color as the track, and a token guarantees that where two literals only
   promise it.
   ============================================================================ */
.insight-card {
  max-width: 42rem;
  margin: 0 auto;
  border: 1px solid var(--rule);
  border-top: 4px solid var(--riot-blue);
  border-radius: 6px;
  text-align: left;
  overflow: hidden;
}
.insight-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: .85rem 1.4rem .1rem;
}
.insight-eyebrow {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.insight-meta {
  font-size: 13px;
  color: var(--ink-faint);
  white-space: nowrap;
}
.insight-body {
  padding: 0 1.4rem 1rem;
}
.insight-title {
  font-size: 23px;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.25;
  margin: .35rem 0 0;
}

/* the countdown track */
.mn-track {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1rem;
  padding: 1.1rem 1.4rem 1.2rem;
  background: var(--rule-soft);
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.mn-track .mn-code {
  flex-shrink: 0;
  margin-top: .45rem;
}
.mn-track-steps {
  display: flex;
  align-items: flex-start;
  flex: 1;
  list-style: none;
  margin: 0;
  padding: 0;
  min-width: 0;
}
.mn-step {
  position: relative;
  flex: 1;
  text-align: center;
  min-width: 0;
}
/* connector runs from the center of the previous step to the center of this one */
.mn-step + .mn-step::before {
  content: "";
  position: absolute;
  left: -50%;
  right: 50%;
  top: .8rem;
  border-top: 2px solid var(--riot-blue);
  opacity: .3;
}
/* z-index is load-bearing. Each connector is an ::before on its own step that
   reaches back into the PREVIOUS step, and .mn-step is position:relative with
   z-index:auto, so it creates no stacking context and DOM order decides paint
   order. Without this, step N+1's line paints over step N's number and its
   background mask: the gap looks right on the left of every value (which masks
   its own connector) and vanishes on the right. Lifting every value to z-index 1
   puts all of them above all connectors, so both gaps are the value's own
   horizontal padding and are equal by construction. */
.mn-step-val {
  position: relative;
  z-index: 1;
  display: inline-block;
  font-size: 21px;
  font-weight: 700;
  color: var(--riot-blue);
  font-variant-numeric: tabular-nums;
  line-height: 1.4;
  background: var(--rule-soft);
  padding: 0 .5rem;
}
/* The terminal step keeps its pill treatment (.pv-secured / .pv-out), so the
   plain background above has to be re-overridden or the pill reads as bare
   text. The pill's own padding shapes the pill and cannot double as the
   connector gap the way a numeral's padding does, so two horizontally-offset
   shadows in the TRACK colour mask the line either side. They must be offsets
   rather than a spread ring: a ring grows in all four directions and covers the
   top of the date underneath.

   Vertical padding matches the numerals' line box (21px x 1.4 = 29.4px against
   13px x 1.4 = 18.2px, so 5.6px top and bottom). Without it the pill is shorter
   than the numbers and the date beneath rides ~4px higher than the rest. */
.mn-step-val.pv-secured,
.mn-step-val.pv-out {
  font-size: 13px;
  font-weight: 700;
  padding: 5.6px 11px;
  border-radius: 999px;
  box-shadow: -.5rem 0 0 0 var(--rule-soft), .5rem 0 0 0 var(--rule-soft);
}
.mn-step-date {
  display: block;
  font-size: 11px;
  color: var(--ink-faint);
  letter-spacing: .04em;
  margin-top: .1rem;
}
/* The opening value has no date to show and says so. Italic and a shade
   lighter so it reads as a different KIND of thing from the dates beside it
   rather than as one more date the reader cannot parse. */
.mn-step-undated {
  font-style: italic;
  opacity: .75;
}
/* --- the insight deck ------------------------------------------------------
   A scroll-snap track and anchor dots, no script. `overflow-x` makes this the
   nearest scrollable ancestor, so clicking a dot scrolls THIS and not the
   page; `scroll-snap-align: center` is what stops it settling between two
   cards. Slides are `flex: 0 0 100%` rather than sized in the track, so one
   card and three lay out identically. */
.insight-track {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* the dots are the affordance; a scrollbar under the card is just furniture */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.insight-track::-webkit-scrollbar { display: none; }
.insight-slide {
  flex: 0 0 100%;
  min-width: 0;
  scroll-snap-align: center;
}
.insight-dots {
  display: flex;
  justify-content: center;
  gap: .55rem;
  margin-top: .8rem;
}
/* The hit area is the anchor and the visible mark is inside it: a 9px dot is
   below every touch-target minimum, and growing the dot to meet one would
   change the design instead of the target. */
.insight-dot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 1.6rem;
  text-decoration: none;
}
.insight-dot-mark {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--riot-blue);
  opacity: .28;
  transition: opacity .15s ease;
}
.insight-dot:hover .insight-dot-mark,
.insight-dot:focus-visible .insight-dot-mark { opacity: .7; }
/* Lit by insight-deck.js, which reads the track's real scroll position rather
   than assuming the last click landed -- the track also moves by swipe and by
   keyboard, and neither goes through the click handler. With scripting off no
   dot is lit, which is dim but honest: nothing there knows where the reader
   is. */
.insight-dot.is-current .insight-dot-mark { opacity: 1; }

/* Only rendered when the track has more than an opening value and a terminal --
   see explanations.INSIGHT_CAPTION for why it is not decoration. */
.insight-caption {
  margin: 0;
  padding: .6rem 1.4rem 0;
  font-size: 12px;
  color: var(--ink-faint);
}
.insight-foot {
  padding: .75rem 1.4rem;
}
/* Stacked: the metric chip drops onto its own line above the steps.
   align-items must flip to center here -- inherited flex-start collapses the
   <ol> to its content width and pins it to the left edge of the card while the
   chip stays centered above it. */
@media (max-width: 575.98px) {
  .mn-track {
    flex-direction: column;
    align-items: center;
    gap: .6rem;
    padding: 1rem .8rem 1.1rem;
  }
  .mn-track .mn-code { margin-top: 0; }
  .mn-track-steps { width: 100%; }
  .mn-step-val { font-size: 18px; padding: 0 .35rem; }
  .mn-step-val.pv-secured,
  .mn-step-val.pv-out { font-size: 12px; padding: 3px 8px; }
  .mn-step-date { font-size: 10px; }
}
