/* The style of the site.
 *
 * A ranked ladder is the subject, so the tiers still carry the color: Iron to
 * Challenger is a scale that a player already reads, and this site uses it for a
 * rank, for a ladder, and for the spine of a table.
 *
 * One brand hue anchors the site: an indigo, `#2b2b88`, not a color that Riot
 * Games already owns. `--brand-deep` holds that anchor. `--brand` holds a
 * lighter step of the same hue, for a control that must read at a working
 * contrast on `--void`. `--win`, `--loss`, and `--gold` hold a triadic and a
 * complementary formula of the anchor, each one adjusted for contrast. The
 * analogous, tetradic, and spectrum tokens hold the anchor's formula at full
 * saturation, for a chart series and not for text. `docs/visuals.md` names
 * the formula and the role of each one.
 *
 * A landing surface (the home page, the head of the ladder, the head of a
 * champion) gets room to breathe. A data surface (a match row, a ladder table,
 * a stat band) stays as tight as `docs/visuals.md` asks. */

:root {
  color-scheme: dark;

  --void: #0f1015;
  --panel: #171821;
  --panel-2: #1f202b;
  --edge: #2d2f3e;
  --ink: #f3f4f8;
  --dim: #8c8f9e;

  --brand: #5252d6;
  --brand-deep: #2b2b88;

  --win: #3fae4c;
  --loss: #c2483f;
  --gold: #c7ab3f;

  /* Analogous accents: a role, a lane, a series of a chart. */
  --analogous-1: #592d86;
  --analogous-2: #2d5986;
  --analogous-3: #852e85;

  /* Tetradic accents: a fourth and a fifth series, when three is not enough. */
  --tetrad-pink: #882b5a;
  --tetrad-teal: #2b885a;

  /* The full spectrum of the formula, for a chart of many series. */
  --spectrum-violet: #882b88;
  --spectrum-red: #882b2b;
  --spectrum-yellow: #88882b;
  --spectrum-green: #2b882b;
  --spectrum-cyan: #2b8888;

  /* The tier of a rank paints the page. A player reads this scale without a legend. */
  --iron: #7c7c7c;
  --bronze: #a06c48;
  --silver: #9aa4ae;
  --tier-gold: #c8a25a;
  --platinum: #4ea5a5;
  --emerald: #3fa463;
  --diamond: #6fa8dc;
  --master: #9b6bd6;
  --grandmaster: #d14b4b;
  --challenger: #e6c36a;

  --page: 76rem;
  --rule: 1px solid var(--edge);
  --gap: 1.5rem;
}

[data-theme='light'] {
  color-scheme: light;

  --void: #f4f5f8;
  --panel: #ffffff;
  --panel-2: #ebecef;
  --edge: #d5d8e1;
  --ink: #0f1015;
  --dim: #626675;

  --brand: #5252d6;
  --brand-deep: #1d1d4f;

  --gold: #89752b;

  /* A tier paints text, and the dark scale is too pale on a light ground. Every color of
   * this scale holds a contrast of 4.5:1 against the panel. */
  --iron: #757575;
  --bronze: #9e6a47;
  --silver: #70777f;
  --tier-gold: #8d733f;
  --platinum: #3c8080;
  --emerald: #338450;
  --diamond: #517aa0;
  --master: #8d61c2;
  --grandmaster: #cc4949;
  --challenger: #89743f;
}

* {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  background: var(--void);
  color: var(--ink);
  font-family:
    'Public Sans',
    system-ui,
    -apple-system,
    'Segoe UI',
    Roboto,
    sans-serif;
  font-size: 16px;
  line-height: 1.55;
  margin: 0;
  min-height: 100vh;
}

h1,
h2,
h3 {
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
  font-optical-sizing: auto;
  font-weight: 600;
  line-height: 1.08;
  margin: 0 0 0.5rem;
  text-wrap: balance;
}

h1 {
  font-size: clamp(1.9rem, 1.2rem + 2.4vw, 3.1rem);
}

h2 {
  font-size: 1.4rem;
}

h3 {
  font-size: 1.1rem;
}

p {
  margin: 0 0 0.75rem;
  max-width: 68ch;
}

a {
  color: var(--brand);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

a:hover {
  color: var(--ink);
}

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

img {
  max-width: 100%;
}

/* The numbers of a table must line up. */
table,
.tabular {
  font-variant-numeric: tabular-nums;
}

/* --- The frame --------------------------------------------------------- */

.site-header {
  align-items: center;
  border-bottom: var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.25rem;
  margin: 0 auto;
  max-width: var(--page);
  padding: 1.1rem 1.25rem;
}

.brand {
  align-items: center;
  color: var(--ink);
  display: flex;
  gap: 0.6rem;
  text-decoration: none;
}

.brand-name {
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.15rem;
  font-weight: 600;
  white-space: nowrap;
}

.logo {
  color: var(--brand);
}

.site-nav {
  margin-left: 0;
}

.site-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-nav a {
  color: var(--dim);
  text-decoration: none;
}

.site-nav a:hover {
  color: var(--ink);
}

/* A group of the bar holds the pages of one subject. The menu of a group stands over
   the page, so a page holds its place while a menu opens. */
.nav-group {
  position: relative;
}

.nav-button {
  background: none;
  border: 0;
  color: var(--dim);
  cursor: pointer;
  font: inherit;
  padding: 0;
}

.nav-button::after {
  content: '';
  border-left: 0.28rem solid transparent;
  border-right: 0.28rem solid transparent;
  border-top: 0.3rem solid currentColor;
  display: inline-block;
  margin-left: 0.35rem;
  vertical-align: 0.1em;
}

.nav-button:hover,
.nav-button[aria-expanded='true'] {
  color: var(--ink);
}

.site-nav [data-current='true'],
.site-nav [aria-current='page'] {
  color: var(--ink);
  font-weight: 600;
}

/* The rule of the bar gives a list a row of its own. A menu is a column, so this rule
   names the bar and stands over that one. */
.site-nav .nav-menu {
  background: var(--panel);
  border: var(--rule);
  border-radius: 0.5rem;
  box-shadow: 0 10px 24px rgb(0 0 0 / 35%);
  display: block;
  left: 0;
  list-style: none;
  margin: 0.6rem 0 0;
  min-width: 11rem;
  padding: 0.35rem;
  position: absolute;
  top: 100%;
  z-index: 20;
}

.site-nav .nav-menu a {
  border-radius: 0.35rem;
  display: block;
  padding: 0.35rem 0.5rem;
  white-space: nowrap;
}

.site-nav .nav-menu a:hover {
  background: var(--panel-2);
}

.theme-toggle {
  background: none;
  border: var(--rule);
  border-radius: 999px;
  color: var(--dim);
  cursor: pointer;
  font: inherit;
  font-size: 0.85rem;
  padding: 0.25rem 0.7rem;
}

.theme-toggle:hover {
  color: var(--ink);
}

main {
  margin: 0 auto;
  max-width: var(--page);
  padding: 2rem 1.25rem 4rem;
}

/* The router moves the focus to the page, and that move is no action of the reader. The
 * ring of a control that the reader reaches with the Tab key stays. */
main:focus {
  outline: none;
}

.site-footer {
  border-top: var(--rule);
  color: var(--dim);
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin: 0 auto;
  max-width: var(--page);
  padding: 1.25rem;
}

.site-footer a {
  color: var(--dim);
}

/* --- The home page: a landing surface, with room to breathe ------------ */

.hero {
  border-radius: 1rem;
  isolation: isolate;
  margin-top: 1rem;
  padding: 2.5rem 1.75rem;
  position: relative;
}

/* A gradient of the brand hue gives the hero its own weight, so the search does not
 * stand on the same flat ground as the rest of the page. The ground of the gradient
 * stays dark in both themes, so one text color reads on it either way. */
.hero::before {
  background:
    radial-gradient(
      60% 90% at 100% 0%,
      color-mix(in srgb, var(--brand) 40%, transparent),
      transparent
    ),
    linear-gradient(160deg, var(--brand-deep), #12121c 75%);
  border-radius: inherit;
  content: '';
  inset: 0;
  position: absolute;
  z-index: -2;
}

/* The splash of one champion, faded into the gradient so the search stays readable. */
.hero-art {
  background-position: top;
  background-size: cover;
  border-radius: inherit;
  inset: 0;
  mask-image: linear-gradient(100deg, transparent 0%, transparent 30%, black 85%);
  opacity: 0.55;
  position: absolute;
  z-index: -1;
}

/* The gradient of the hero stays dark in both themes, so its own text stays light in
 * both themes too, instead of following `--ink`. */
.hero {
  color: #f3f4f8;
}

.hero label,
.hero .hint {
  color: #b6b8c9;
}

.hero .secondary {
  border-color: rgba(255, 255, 255, 0.35);
  color: #f3f4f8;
}

.hero-content {
  max-width: 34rem;
}

.hero h1 {
  font-size: clamp(2.2rem, 1.5rem + 2.8vw, 3.6rem);
}

.hero p {
  color: #b6b8c9;
  font-size: 1.08rem;
  max-width: 40ch;
}

@media (max-width: 40rem) {
  .hero {
    padding: 1.75rem 1.25rem;
  }

  .hero-art {
    mask-image: linear-gradient(to bottom, transparent 0%, transparent 55%, black 100%);
    opacity: 0.3;
  }
}

.search {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 1.5rem 0 0.75rem;
}

.search .field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin: 0;
}

.search .field:first-child {
  flex: 1 1 20rem;
}

label {
  color: var(--dim);
  font-size: 0.85rem;
}

input[type='text'],
input[type='search'],
select {
  background: var(--panel);
  border: var(--rule);
  border-radius: 0.4rem;
  color: var(--ink);
  font: inherit;
  padding: 0.6rem 0.7rem;
}

input[type='text']:focus,
input[type='search']:focus,
select:focus {
  border-color: var(--brand);
}

button {
  background: var(--brand);
  border: 1px solid transparent;
  border-radius: 0.4rem;
  color: #ffffff;
  cursor: pointer;
  font: inherit;
  font-weight: 600;
  padding: 0.6rem 1.1rem;
}

button:hover {
  filter: brightness(1.1);
}

button[disabled] {
  cursor: progress;
  opacity: 0.6;
}

.hint {
  color: var(--dim);
  font-size: 0.9rem;
}

/* Three ways into the site. A rule carries the eye, and not a box. */
.entries {
  border-top: var(--rule);
  display: grid;
  gap: 0;
  margin-top: 2.5rem;
}

/* The steps of the landing page are an ordered list, and the number of a step stands
 * in the column of the title. The marker of the browser adds a second number, so this
 * list carries none. */
.entries.steps {
  list-style: none;
  padding-left: 0;
}

.entry {
  border-bottom: var(--rule);
  display: grid;
  gap: 0.3rem 1.5rem;
  grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
  padding: 1.5rem 0;
}

.entry h3 {
  font-size: 1.15rem;
  margin: 0;
}

.entry h3 a {
  color: var(--ink);
  text-decoration: none;
}

.entry h3 a:hover {
  color: var(--brand);
}

/* An entry of "your page" without a page of its own carries no heading and no link, so
 * it does not read as clickable. */
.feature-static {
  color: var(--ink);
  font-size: 1.15rem;
  font-weight: normal;
  margin: 0;
}

.entry p {
  color: var(--dim);
  margin: 0;
}

@media (max-width: 40rem) {
  .entry {
    grid-template-columns: 1fr;
  }
}

/* --- The profile --------------------------------------------------------- */

.profile-header {
  display: grid;
  gap: var(--gap);
  grid-template-columns: minmax(0, 24rem) minmax(0, 1fr);
  padding-bottom: 1.5rem;
}

@media (max-width: 46rem) {
  .profile-header {
    grid-template-columns: 1fr;
  }
}

.identity {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.profile-icon {
  border: 2px solid var(--edge);
  border-radius: 0.6rem;
  height: 84px;
  width: 84px;
}

.profile-identity h1 {
  font-size: 1.7rem;
  overflow-wrap: break-word;
}

.profile-meta {
  color: var(--dim);
  font-size: 0.9rem;
  margin: 0;
}

.profile-links {
  display: flex;
  gap: 1rem;
  margin-top: 0.5rem;
}

.rank-list {
  display: grid;
  gap: 0.75rem;
}

/* The tier paints the spine of a rank, and not a whole box. The league points stand at
 * the right, beside the tier that earned them. */
.rank-card {
  align-items: center;
  border-left: 4px solid var(--tier, var(--edge));
  display: grid;
  gap: 0 1rem;
  grid-template-areas:
    'queue lp'
    'tier lp'
    'record lp';
  grid-template-columns: minmax(0, 1fr) auto;
  max-width: 26rem;
  padding: 0.6rem 0 0.6rem 0.9rem;
}

.rank-card h2 {
  grid-area: queue;
}

.rank-tier {
  grid-area: tier;
}

.rank-record {
  grid-area: record;
}

.rank-card h2 {
  color: var(--dim);
  font-size: 0.85rem;
  font-weight: 600;
  margin: 0;
}

.rank-tier {
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.2rem;
  font-weight: 600;
  margin: 0;
}

.rank-card .rank-lp {
  color: var(--tier, var(--ink));
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.1rem;
  font-weight: 600;
  grid-area: lp;
  margin: 0;
  text-align: right;
}

.rank-card p {
  color: var(--dim);
  font-size: 0.9rem;
  margin: 0;
}

/* --- The tables: a data surface, kept tight ----------------------------- */

.matches {
  border-collapse: collapse;
  font-size: 0.92rem;
  width: 100%;
}

.matches caption {
  color: var(--dim);
  font-size: 0.9rem;
  padding-bottom: 0.6rem;
  text-align: left;
}

.matches th,
.matches td {
  border-bottom: var(--rule);
  padding: 0.55rem 0.6rem;
  text-align: left;
  vertical-align: middle;
}

.matches thead th {
  color: var(--dim);
  font-size: 0.8rem;
  font-weight: 600;
}

.matches tbody th {
  font-weight: 600;
}

.champion-cell {
  align-items: center;
  display: flex;
  gap: 0.55rem;
}

.champion-cell img {
  border-radius: 0.3rem;
  height: 32px;
  width: 32px;
}

.items {
  display: flex;
  gap: 0.2rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.items img {
  border-radius: 0.25rem;
  height: 24px;
  width: 24px;
}

.table-scroll {
  overflow-x: auto;
}

/* --- The champions -------------------------------------------------------- */

.toolbar {
  align-items: flex-end;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: 1.25rem;
}

.toolbar .field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin: 0;
}

/* A field of many values. The summary reads like a `select`, and the body of it holds
   one box for each value. A `details` element needs no script for that. */
.picker {
  position: relative;
}

.picker > summary {
  background: var(--panel);
  border: var(--rule);
  border-radius: 0.4rem;
  color: var(--ink);
  cursor: pointer;
  font: inherit;
  list-style: none;
  padding: 0.6rem 0.7rem;
  user-select: none;
  white-space: nowrap;
}

/* The two rules below remove the triangle that a browser draws for a `summary`. */
.picker > summary::-webkit-details-marker {
  display: none;
}

.picker > summary::marker {
  content: '';
}

.picker > summary::after {
  content: '\25be';
  margin-left: 0.6rem;
}

.picker[open] > summary,
.picker > summary:focus-visible {
  border-color: var(--brand);
}

.picker-menu {
  background: var(--panel);
  border: var(--rule);
  border-radius: 0.5rem;
  box-shadow: 0 10px 24px rgb(0 0 0 / 35%);
  display: grid;
  gap: 0.35rem;
  left: 0;
  margin-top: 0.3rem;
  max-height: 18rem;
  min-width: 100%;
  overflow-y: auto;
  padding: 0.5rem 0.6rem;
  position: absolute;
  top: 100%;
  z-index: 20;
}

.picker-menu label {
  align-items: center;
  border-radius: 0.35rem;
  cursor: pointer;
  display: flex;
  gap: 0.45rem;
  padding: 0.2rem 0.3rem;
  white-space: nowrap;
}

.picker-menu label:hover {
  background: var(--panel-2);
}

.roles {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.role {
  background: none;
  border: var(--rule);
  border-radius: 999px;
  color: var(--dim);
  font-size: 0.85rem;
  font-weight: 500;
  padding: 0.3rem 0.8rem;
}

.role[aria-pressed='true'] {
  background: var(--brand);
  border-color: var(--brand);
  color: #ffffff;
}

.grid {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  list-style: none;
  margin: 0;
  padding: 0;
}

.champion-card a {
  align-items: center;
  color: var(--ink);
  display: flex;
  gap: 0.6rem;
  text-decoration: none;
}

.champion-card {
  border-bottom: var(--rule);
  padding: 0.6rem 0;
}

.champion-card img {
  border-radius: 0.35rem;
  height: 40px;
  width: 40px;
}

.champion-card p {
  color: var(--dim);
  font-size: 0.85rem;
  margin: 0.25rem 0 0;
}

/* The splash carries the page. It is the one loud thing here. */
.champion-banner {
  align-items: flex-end;
  background-position: center 22%;
  background-size: cover;
  border-radius: 0.75rem;
  display: flex;
  margin-bottom: 1.75rem;
  min-height: 21rem;
  padding: 1.75rem;
  position: relative;
}

/* A fixed height crops the splash harder as the screen narrows, because the cover
 * keeps the full height and throws more of the width away. The aspect ratio ties
 * the height to the width instead, so the crop of the splash stays the same. */
@media (max-width: 40rem) {
  .champion-banner {
    aspect-ratio: 3 / 2;
    min-height: 0;
  }
}

/* The scrim sits on the artwork, so it stays dark in both themes. A light ground under
 * white lettering has no contrast. */
.champion-banner::after {
  background: linear-gradient(
    to top,
    rgba(8, 8, 24, 0.95) 2%,
    rgba(8, 8, 24, 0.65) 40%,
    rgba(8, 8, 24, 0.15)
  );
  border-radius: inherit;
  content: '';
  inset: 0;
  position: absolute;
}

.champion-banner > * {
  position: relative;
  z-index: 1;
}

.champion-banner h1 {
  color: #f8f7fc;
  margin: 0;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.55);
}

.champion-banner .champion-title {
  color: #dcdaf2;
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.1rem;
  font-style: italic;
  margin: 0;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.6);
}

.tags {
  color: var(--dim);
  font-size: 0.9rem;
}

.ability {
  border-top: var(--rule);
  display: grid;
  gap: 0.2rem 1rem;
  grid-template-columns: 44px minmax(0, 1fr);
  padding: 1rem 0;
}

.ability img {
  border-radius: 0.3rem;
  grid-row: span 2;
  height: 44px;
  width: 44px;
}

.ability p {
  color: var(--dim);
  margin: 0;
}

/* The icon spans the row of the name and the row of the text, so an item after the text
 * lands under the icon by default. This keeps the numbers under the text instead, in
 * one row.
 */
.ability-numbers {
  grid-column: 2;
}

/* --- The ladder ---------------------------------------------------------- */

.tier-head {
  align-items: baseline;
  border-left: 4px solid var(--tier, var(--edge));
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2.5rem;
  padding-left: 0.9rem;
}

.tier-head h2 {
  color: var(--tier, var(--ink));
  margin: 0;
}

.tier-head p {
  color: var(--dim);
  font-size: 0.9rem;
  margin: 0;
}

.ladder-place {
  color: var(--dim);
  width: 3rem;
}

/* --- The states -------------------------------------------------------- */

.spinner {
  color: var(--dim);
}

.notice {
  border-left: 3px solid var(--gold);
  padding-left: 1rem;
}

.mastery-card {
  align-items: center;
  border-bottom: var(--rule);
  display: flex;
  gap: 0.7rem;
  padding: 0.6rem 0;
}

.mastery-card .icon-holder {
  flex-shrink: 0;
}

.mastery-card img {
  aspect-ratio: 1;
  border-radius: 0.35rem;
  height: 40px;
  object-fit: cover;
  width: 40px;
}

.mastery-card p {
  margin: 0;
}

.mastery-points {
  color: var(--dim);
  font-size: 0.85rem;
}

.team {
  border-left: 4px solid var(--edge);
  margin: 1.25rem 0;
  padding-left: 0.9rem;
}

.team-100 {
  border-left-color: var(--brand);
}

.team-200 {
  border-left-color: var(--loss);
}

.team ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.team li {
  border-bottom: var(--rule);
  padding: 0.4rem 0;
}

.team .live-name {
  color: var(--dim);
}

.row-actions {
  display: flex;
  gap: 0.75rem;
  margin: 0;
}

.more {
  margin-top: 1.25rem;
}

/* The second action of a pair carries no fill. One page has one loud button. */
.secondary {
  background: none;
  border: var(--rule);
  color: var(--ink);
}

.secondary:hover {
  border-color: var(--brand);
  filter: none;
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }
}

/* A narrow screen puts the navigation under the name, and nothing leaves the page. */
@media (max-width: 30rem) {
  .site-header {
    gap: 0.5rem 1rem;
    padding: 0.75rem 1rem;
  }

  .site-nav {
    margin-left: 0;
    order: 3;
    width: 100%;
  }

  main {
    padding: 1.5rem 1rem 3rem;
  }

  .site-footer {
    padding: 1rem;
  }

  .search .field:first-child {
    flex: 1 1 100%;
  }
}

/* --- The match list: a data surface, kept tight -------------------------- */

/* The result paints the whole row. A spine of three pixels does not read from a
 * distance, and every large site of this kind paints the ground. */
.match-list {
  display: grid;
  gap: 0.3rem;
}

/* The button sits over the row and takes no track, so a narrow screen never squeezes a
 * block into two characters. */
.match-row {
  align-items: center;
  border-left: 3px solid var(--edge);
  border-radius: 0.3rem;
  cursor: pointer;
  display: grid;
  font-size: 0.82rem;
  gap: 0.4rem 0.6rem;
  grid-template-columns:
    minmax(5.5rem, 0.7fr)
    minmax(9.5rem, 1.2fr)
    minmax(6rem, 0.7fr)
    minmax(7.5rem, 1fr)
    minmax(7rem, 0.9fr)
    minmax(9rem, 1.1fr);
  line-height: 1.35;
  padding: 0.4rem 2rem 0.4rem 0.6rem;
  position: relative;
}

.match-row.win {
  background: color-mix(in srgb, var(--win) 14%, var(--void));
  border-left-color: var(--win);
}

.match-row.loss {
  background: color-mix(in srgb, var(--loss) 14%, var(--void));
  border-left-color: var(--loss);
}

/* A remake counts for no rank. The row of a remake thus carries no color of a result,
   and it stands back from the rows around it. */
.match-row.remake {
  background: color-mix(in srgb, var(--dim) 10%, var(--void));
  border-left-color: var(--dim);
}

.match-row.remake .result {
  color: var(--dim);
}

.match-row .block p {
  margin: 0;
  max-width: none;
}

.block.when {
  display: grid;
  gap: 0;
}

.match-row .queue {
  font-weight: 600;
}

.match-row .played,
.match-row .length,
.match-row .lane,
.match-row .ratio,
.quiet {
  color: var(--dim);
  font-size: 0.85rem;
}

/* A match row is a data surface, so every line of it stays as tight as the grid. */
.match-row .played,
.match-row .length,
.match-row .lane,
.match-row .ratio,
.match-row .quiet {
  font-size: 0.76rem;
}

.score-line {
  border-bottom: 1px dotted var(--dim);
  cursor: help;
  display: inline-block;
}

.match-row .result {
  font-family: 'Fraunces', Georgia, serif;
  font-weight: 600;
}

.match-row.win .result {
  color: var(--win);
}

.match-row.loss .result {
  color: var(--loss);
}

.block.champion {
  align-items: center;
  display: flex;
  gap: 0.5rem;
}

.block.champion .face {
  border-radius: 0.3rem;
  height: 40px;
  width: 40px;
}

.marks {
  display: grid;
  gap: 0.15rem;
}

/* The spells and the keystone read as one group with the items, so they stand in two
   columns beside the build and not beside the face of the champion. */
.block.match-build {
  align-items: center;
  display: flex;
  gap: 0.35rem;
}

.block.match-build .marks {
  align-items: start;
  grid-auto-flow: column;
}

.marks img {
  border-radius: 0.2rem;
  display: block;
  height: 22px;
  width: 22px;
}

.spells {
  display: grid;
  gap: 0.15rem;
}

.marks .rune {
  background: var(--void);
  border-radius: 50%;
}

.block.champion .named p:first-child {
  font-weight: 600;
}

.block.score .kda {
  font-family: 'Fraunces', Georgia, serif;
  font-size: 0.95rem;
  font-weight: 600;
}

.block.numbers p {
  font-size: 0.78rem;
}

/* The three steps of a measure of a match row. `docs/visuals.md` names the limits.
   A number under the first limit stands back, a number over the second one stands out. */
.metric.low {
  color: var(--dim);
}

/* The brand hue alone is dark on the ground of a lost match, so the step of the
   middle mixes that hue with the text color of the page. The hue stays the brand. */
.metric.good {
  color: color-mix(in srgb, var(--brand) 75%, var(--ink));
}

.metric.great {
  color: var(--gold);
}

/* A step paints the whole line, so the part in the brackets carries no other color. */
.metric span {
  color: inherit;
}

.items {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.items img {
  background: var(--void);
  border-radius: 0.25rem;
  height: 24px;
  width: 24px;
}

.items .empty {
  color: var(--dim);
  font-size: 0.85rem;
}

/* The build of a match row. The six items pack a grid of three columns and two rows.
   The trinket and the item of the role stand in one column beside that grid. */
.match-row .build {
  align-items: start;
  display: flex;
  gap: 0.25rem;
}

.match-row .build .items {
  display: grid;
  gap: 0.15rem;
  grid-template-columns: repeat(3, 24px);
  grid-template-rows: repeat(2, 24px);
}

.match-row .build .items.aside {
  grid-template-columns: 24px;
}

.match-row .build .items .empty {
  grid-column: 1 / -1;
  font-size: 0.76rem;
}

/* An empty cell keeps the item of the role under the trinket, and the trinket in the
   upper cell of a build without an item of a role. */
.match-row .build .hole {
  height: 24px;
  width: 24px;
}

.team-list {
  display: grid;
  gap: 0.1rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.team-list li {
  align-items: center;
  display: flex;
  gap: 0.3rem;
  overflow: hidden;
}

.team-list img {
  border-radius: 0.2rem;
  flex: none;
  height: 16px;
  width: 16px;
}

.team-list a {
  color: var(--dim);
  font-size: 0.78rem;
  overflow: hidden;
  text-decoration: none;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.team-list a:hover {
  color: var(--ink);
}

.block.teams {
  display: grid;
  gap: 0.5rem;
  grid-template-columns: 1fr 1fr;
}

.expand {
  background: none;
  border: var(--rule);
  border-radius: 0.3rem;
  color: var(--dim);
  font-size: 0.9rem;
  line-height: 1;
  padding: 0.15rem 0.4rem;
  position: absolute;
  right: 0.4rem;
  top: 0.4rem;
}

.expand:hover {
  color: var(--ink);
}

/* The open panel carries its own tone, so a reader sees where the row ends and the
   detail of that row starts. The tone is the second surface, over the tint of the
   result. The panel holds its own controls, so the row cursor stops here. */
.match-panel {
  background: var(--panel-2);
  border: var(--rule);
  border-radius: 0.3rem;
  cursor: auto;
  grid-column: 1 / -1;
  margin-top: 0.4rem;
  padding: 0.6rem;
}

.panel-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-bottom: 0.6rem;
}

.panel-tab {
  background: none;
  border: var(--rule);
  border-radius: 999px;
  color: var(--dim);
  cursor: pointer;
  font: inherit;
  font-size: 0.8rem;
  padding: 0.2rem 0.7rem;
}

.panel-tab:hover {
  color: var(--ink);
}

.panel-tab[aria-selected='true'] {
  background: var(--brand);
  border-color: var(--brand);
  color: #ffffff;
}

.panel-table {
  font-size: 0.85rem;
}

/* The shop of one player. Every step holds an icon over a minute. */
.purchases {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.purchases li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
}

.purchases img {
  border-radius: 4px;
  display: block;
}

.purchases .minute {
  color: var(--dim);
  font-size: 0.7rem;
}

/* A sale carries a red frame beside the word `Sold`, because a color alone tells a
 * reader without color vision nothing. */
.purchases .sold img {
  outline: 2px solid var(--loss);
  outline-offset: -2px;
}

.purchases .sold .minute {
  color: var(--loss);
}

/* The rune pages of the Runes tab stand in one column, because the panel is narrow. */
.panel-section .rune-cards {
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}

/* The order of the abilities of one player. Every step holds a letter over a level. */
.skill-order {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.skill-order li {
  align-items: center;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.skill-order .letter {
  background: var(--panel);
  border: var(--rule);
  border-radius: 0.3rem;
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1;
  padding: 0.25rem 0.35rem;
}

/* The last ability of a champion is the strongest one, and it carries the color. */
.skill-order .skill-r {
  border-color: var(--brand);
  color: var(--brand);
}

.skill-order .step {
  color: var(--dim);
  font-size: 0.7rem;
}

.side-blue tr th {
  border-left: 3px solid var(--brand);
}

.side-red tr th {
  border-left: 3px solid var(--loss);
}

.bar-cell {
  min-width: 8rem;
}

.bar {
  background: var(--edge);
  border-radius: 999px;
  display: inline-block;
  height: 0.45rem;
  margin-right: 0.4rem;
  overflow: hidden;
  vertical-align: middle;
  width: 4.5rem;
}

.bar > span {
  background: var(--brand);
  display: block;
  height: 100%;
}

.bar-value {
  font-variant-numeric: tabular-nums;
}

@media (max-width: 72rem) {
  .match-row {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) minmax(0, 1fr);
  }

  /* The build holds one short row of icons. Without a span of its own, the grid
   * leaves it beside an empty cell, because the row of the ten names below needs
   * every column of a row to itself. */
  .block.match-build,
  .block.teams {
    grid-column: 1 / -1;
  }
}

@media (max-width: 46rem) {
  .match-row {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

@media (max-width: 32rem) {
  .match-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .block.teams {
    grid-template-columns: 1fr 1fr;
  }
}

/* --- The summary of the last games --------------------------------------- */

.summary {
  border-bottom: var(--rule);
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  margin-bottom: 1.5rem;
  padding-bottom: 1.25rem;
}

.summary-block {
  align-items: center;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  justify-content: center;
}

.summary-block p {
  margin: 0;
  text-align: center;
}

.summary-block.band p:first-child {
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.35rem;
  font-weight: 600;
}

/* One arc holds one percent. */
.ring {
  align-items: center;
  aspect-ratio: 1;
  background: conic-gradient(var(--win) var(--angle), var(--edge) 0);
  border-radius: 50%;
  display: flex;
  height: 5rem;
  justify-content: center;
  position: relative;
}

.ring::before {
  background: var(--void);
  border-radius: 50%;
  content: '';
  inset: 0.5rem;
  position: absolute;
}

.ring-value {
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.1rem;
  font-weight: 600;
  position: relative;
}

.top-champions,
.lanes {
  display: grid;
  gap: 0.3rem;
  list-style: none;
  margin: 0;
  padding: 0;
  width: 100%;
}

.top-champions li {
  align-items: center;
  display: grid;
  gap: 0.5rem;
  grid-template-columns: 28px minmax(0, 1fr);
}

.top-champions img {
  border-radius: 0.25rem;
  grid-row: span 2;
}

.top-champions .named {
  font-size: 0.9rem;
  font-weight: 600;
}

.top-champions .quiet {
  font-size: 0.78rem;
}

.lanes li {
  align-items: center;
  display: grid;
  gap: 0.5rem;
  grid-template-columns: 4rem minmax(0, 1fr) 2.5rem;
}

.lanes .lane-name {
  color: var(--dim);
  font-size: 0.8rem;
}

.lanes .bar {
  /* The track of the default sits close to the page of the dark theme. A higher bar with
   * a track of its own gives the reader the full width of a lane. */
  background: color-mix(in srgb, var(--ink) 14%, transparent);
  height: 0.6rem;
  margin: 0;
  width: 100%;
}

.lanes .quiet {
  font-size: 0.78rem;
  text-align: right;
}

/* --- The champion page --------------------------------------------------- */

.ability-head {
  align-items: baseline;
  display: flex;
  gap: 0.5rem;
}

/* The key that a player presses carries the ability. */
.ability-key {
  background: var(--panel);
  border: var(--rule);
  border-radius: 0.25rem;
  color: var(--brand);
  font-family: 'Fraunces', Georgia, serif;
  font-size: 0.75rem;
  font-weight: 700;
  min-width: 1.4rem;
  padding: 0.05rem 0.35rem;
  text-align: center;
}

/* A band of numbers with a hairline between them. */
.stat-band {
  border: var(--rule);
  border-radius: 0.5rem;
  display: grid;
  gap: 0;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  list-style: none;
  margin: 0 0 1rem;
  overflow: hidden;
  padding: 0;
}

.stat-band li {
  border-bottom: var(--rule);
  border-right: var(--rule);
  display: grid;
  gap: 0.1rem;
  padding: 0.6rem 0.8rem;
}

.stat-band li span:first-child {
  color: var(--dim);
  font-size: 0.78rem;
}

.stat-band li span:last-child {
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.05rem;
  font-weight: 600;
}

.tips {
  color: var(--dim);
  display: grid;
  gap: 0.4rem;
  margin: 0 0 1rem;
  padding-left: 1.1rem;
}

.tips li {
  max-width: 68ch;
}

.skins {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  list-style: none;
  margin: 0;
  padding: 0;
}

.skins li {
  display: grid;
  gap: 0.3rem;
}

.skins img {
  aspect-ratio: 16 / 9;
  border-radius: 0.4rem;
  object-fit: cover;
  object-position: center 20%;
  width: 100%;
}

.skins span {
  color: var(--dim);
  font-size: 0.85rem;
}

.skin-banner {
  background: none;
  border: none;
  cursor: pointer;
  display: block;
  padding: 0;
}

.skin-banner img {
  transition: transform 0.15s ease;
}

.skin-banner:hover img,
.skin-banner:focus-visible img {
  transform: scale(1.03);
}

/* The popup grows sideways out of the banner that opened it, so a click reads as the
 * banner itself widening into the full picture. */
.skin-dialog {
  background: var(--panel);
  border: var(--rule);
  border-radius: 0.75rem;
  color: inherit;
  max-height: 85vh;
  max-width: min(90vw, 56rem);
  opacity: 0;
  overflow-y: auto;
  padding: 1rem;
  transform: scaleX(0.4);
  transform-origin: left center;
  transition:
    transform 0.22s ease,
    opacity 0.22s ease;
}

.skin-dialog.open {
  opacity: 1;
  transform: scaleX(1);
}

.skin-dialog::backdrop {
  background: rgba(8, 8, 24, 0.65);
}

.skin-dialog-close {
  background: none;
  border: none;
  color: var(--dim);
  cursor: pointer;
  float: right;
  font-size: 1.4rem;
  line-height: 1;
  padding: 0.2rem;
}

.skin-dialog-image {
  border-radius: 0.4rem;
  clear: both;
  max-width: 100%;
  width: 100%;
}

.skin-dialog-name {
  font-weight: 600;
  margin: 0.75rem 0 0;
}

.skin-dialog-chromas {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.75rem;
}

.skin-dialog-chroma {
  background: none;
  border: var(--rule);
  border-radius: 999px;
  color: var(--dim);
  cursor: pointer;
  font-size: 0.8rem;
  padding: 0.15rem 0.6rem;
}

.skin-dialog-chroma[aria-pressed='true'] {
  border-color: currentColor;
  color: inherit;
}

/* --- The catalogs -------------------------------------------------------- */

.catalog {
  display: grid;
  gap: 0;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
}

.catalog-card {
  align-items: center;
  border-bottom: var(--rule);
  display: grid;
  gap: 0.6rem;
  grid-template-columns: 32px minmax(0, 1fr) auto;
  padding: 0.5rem 0.6rem 0.5rem 0;
}

.catalog-card img {
  background: var(--void);
  border-radius: 0.25rem;
}

.catalog-card .quiet {
  font-size: 0.85rem;
}

/* The card of an item holds one link, and the link holds the columns: the icon, the
 * name, and the price. The card must give its full width to that link. A card with the
 * columns of the row puts the link in the first column of 32px, and the name then paints
 * over the price. */

.catalog-card-link {
  display: block;
  padding: 0;
}

.catalog-card a {
  align-items: center;
  color: inherit;
  display: grid;
  gap: 0.6rem;
  grid-template-columns: 32px minmax(0, 1fr) auto;
  padding: 0.5rem 0.6rem 0.5rem 0;
  text-decoration: none;
  width: 100%;
}

.catalog-card a:hover {
  color: var(--brand);
}

/* --- The header search --------------------------------------------------- */

/* A rule of this sheet gives many elements a `display`, and that value wins over the
 * `display: none` of the browser for the attribute `hidden`. Every filter of this site
 * writes that attribute, so the rule of the attribute must win. */

[hidden] {
  display: none !important;
}

.visually-hidden {
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

.header-search {
  display: flex;
  gap: 0.35rem;
  margin-left: auto;
}

.header-search input {
  max-width: 11rem;
  padding: 0.35rem 0.5rem;
}

.header-search select {
  padding: 0.35rem 0.4rem;
}

.header-search button {
  padding: 0.35rem 0.8rem;
}

/* --- The ladder chips and podium ------------------------------------------ */

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-bottom: 1rem;
}

.chip {
  border: var(--rule);
  border-radius: 999px;
  color: var(--dim);
  font-size: 0.85rem;
  padding: 0.2rem 0.7rem;
  text-decoration: none;
}

.chip:hover {
  color: var(--ink);
}

.chip[aria-current='page'] {
  background: var(--brand);
  border-color: var(--brand);
  color: #ffffff;
}

button.chip {
  background: none;
  cursor: pointer;
  font: inherit;
}

button.chip[aria-pressed='true'] {
  border-color: var(--brand);
  color: var(--brand);
}

.podium {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: 1rem 0 1.25rem;
}

/* Place 1 carries the full width. Place 2 and place 3 carry one half each, under it. */

.podium-card:first-child {
  grid-column: 1 / -1;
  padding: 1.1rem 1.3rem;
}

.podium-card:first-child .place {
  font-size: 2.4rem;
}

.podium-card:first-child .emblem {
  height: 2.4rem;
  width: 2.4rem;
}

.podium-card:first-child .row-icon {
  height: 2.6rem;
  width: 2.6rem;
}

.podium-card:first-child .podium-name {
  font-size: 1.3rem;
}

/* A card over the full width holds one row: the place, the player, and the record. A
 * narrow screen holds no such row, so place 1 stacks there like place 2. */

@media (min-width: 40rem) {
  .podium-card:first-child {
    align-items: center;
    column-gap: 1rem;
    grid-template-areas:
      'place emblem icon name lp'
      'place emblem icon bar bar';
    grid-template-columns: auto auto auto minmax(0, 1fr) auto;
  }

  .podium-card:first-child .place {
    grid-area: place;
  }

  .podium-card:first-child .emblem {
    grid-area: emblem;
    margin: 0;
  }

  .podium-card:first-child .row-icon {
    grid-area: icon;
  }

  .podium-card:first-child .podium-name {
    grid-area: name;
  }

  .podium-card:first-child .tabular {
    grid-area: lp;
  }

  .podium-card:first-child .win-bar {
    grid-area: bar;
  }
}

@media (max-width: 40rem) {
  .podium {
    grid-template-columns: minmax(0, 1fr);
  }
}

.podium-card {
  border: var(--rule);
  border-left: 4px solid var(--tier, var(--edge));
  border-radius: 0.5rem;
  color: var(--ink);
  display: grid;
  gap: 0.2rem;
  padding: 0.7rem 0.9rem;
  text-decoration: none;
}

.podium-card .place {
  color: var(--tier, var(--dim));
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.45rem;
  font-weight: 600;
  line-height: 1;
}

.podium-name {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* One bar for the wins and the losses, with the record at the end. */
.win-bar {
  align-items: center;
  /* The two parts of the bar carry the full color. A part that mixes with the page turns
   * into one muted tone, and the text over that tone is hard to read. */
  background: var(--loss);
  border-radius: 999px;
  display: inline-flex;
  height: 1.05rem;
  min-width: 7rem;
  overflow: hidden;
  position: relative;
}

.win-bar .won {
  background: var(--win);
  height: 100%;
  left: 0;
  position: absolute;
  top: 0;
}

.win-text {
  /* The text stands over the green part and over the red part of the bar, so it holds
   * one color of its own, and a shadow that holds that color apart from both parts. */
  color: #ffffff;
  font-size: 0.75rem;
  font-weight: 600;
  padding: 0 0.5rem;
  position: relative;
  text-shadow: 0 1px 2px rgb(0 0 0 / 55%);
  white-space: nowrap;
}

/* --- The live game ------------------------------------------------------- */

.live-teams {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
}

.live-list {
  display: grid;
  gap: 0.35rem;
  list-style: none;
  margin: 0 0 0.75rem;
  padding: 0;
}

.live-list li {
  align-items: center;
  border-bottom: var(--rule);
  display: grid;
  gap: 0.5rem;
  /* The row holds four children: the champion, the two summoner spells, the keystone,
   * and the name. A grid of three columns puts the name in the first column of a second
   * row, 32 pixels wide, and the name then breaks over four lines. */
  grid-template-columns: 32px 22px 22px minmax(0, 1fr);
  padding: 0.35rem 0;
}

.live-list img {
  border-radius: 0.25rem;
}

.live-list .named {
  display: grid;
}

.live-list .quiet {
  font-size: 0.78rem;
}

.live-list .runes {
  display: inline-flex;
}

.ban-list img {
  filter: grayscale(0.6);
}

@media (max-width: 60rem) {
  .header-search {
    order: 3;
    width: 100%;
  }

  /* The bar wraps on a narrow screen, and a menu that stands over the page then covers
     the page under it. The menu of a narrow screen stands in the bar. */
  .site-nav .nav-menu {
    box-shadow: none;
    margin-top: 0.35rem;
    position: static;
  }

  .header-search input {
    flex: 1 1 auto;
    max-width: none;
  }
}

/* --- What the reader opened before --------------------------------------- */

.recent-list {
  border-top: var(--rule);
  margin-top: 1.75rem;
  padding-top: 1.25rem;
}

.recent-list .chips {
  list-style: none;
  margin: 0;
  padding: 0;
}

.recent-list .chip {
  align-items: center;
  display: inline-flex;
  gap: 0.35rem;
}

.recent-list img {
  border-radius: 0.2rem;
}

/* The level sits on the icon, as every site of this kind shows it. */
.icon-holder {
  display: inline-block;
  position: relative;
}

.icon-holder .level {
  background: var(--panel);
  border: var(--rule);
  border-radius: 999px;
  bottom: -0.4rem;
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  left: 50%;
  padding: 0.05rem 0.45rem;
  position: absolute;
  transform: translateX(-50%);
}

.match-row .champion .icon-holder .level,
.mastery-card .icon-holder .level {
  font-size: 0.65rem;
}

/* The scoreboard of a match holds ten icons in a narrow table, so the level is small
   and it stands on the icon. */
.panel-table .icon-holder .level {
  bottom: -0.3rem;
  font-size: 0.6rem;
  padding: 0 0.3rem;
}

.rank-card .rank-record {
  align-items: center;
  display: flex;
  gap: 0.4rem;
}

/* --- One item, and the parts of that item -------------------------------- */

.item-head {
  align-items: flex-start;
  display: flex;
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.item-head img {
  border: var(--rule);
  border-radius: 8px;
}

.item-head h1 {
  line-height: 1.1;
  margin: 0 0 0.25rem;
}

.item-head .chips {
  margin-top: 0.5rem;
}

.recipe {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  list-style: none;
  padding: 0;
}

.recipe a {
  align-items: center;
  border: var(--rule);
  border-radius: 999px;
  display: flex;
  gap: 0.5rem;
  padding: 0.35rem 0.7rem;
  text-decoration: none;
}

.recipe a:hover {
  border-color: var(--brand);
}

/* --- The head of the profile: the star, and the splash of the champion --- */

.profile-header {
  isolation: isolate;
  position: relative;
}

.profile-header.has-splash::before {
  background-image: var(--splash);
  background-position: center 22%;
  background-size: cover;
  content: '';
  inset: -1.5rem -1.5rem 0;
  mask-image: linear-gradient(to bottom, rgb(0 0 0 / 85%), transparent 85%);
  opacity: 0.18;
  position: absolute;
  z-index: -1;
}

/* The picture over a light ground gives a gray wash at a low opacity. A multiply keeps
 * the colors of the picture, and the text over it keeps its contrast. */

[data-theme='light'] .profile-header.has-splash::before {
  mix-blend-mode: multiply;
  opacity: 0.22;
}

.profile-header > * {
  position: relative;
}

.profile-keep {
  align-items: flex-end;
  align-self: flex-start;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-left: auto;
}

.star {
  background: none;
  border: var(--rule);
  border-radius: 999px;
  color: var(--dim);
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
  padding: 0.35rem 0.6rem;
}

.star[aria-pressed='true'] {
  border-color: var(--gold);
  color: var(--gold);
}

/* --- The emblem of a tier -------------------------------------------------- */

.emblem {
  height: 1.4rem;
  margin-right: 0.45rem;
  vertical-align: -0.3rem;
  width: 1.4rem;
}

/* --- The strip of the live game, over the last matches -------------------- */

.live-strip {
  align-items: center;
  border: var(--rule);
  border-radius: 0.6rem;
  color: inherit;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-bottom: 1rem;
  padding: 0.6rem 0.9rem;
  text-decoration: none;
}

.live-strip:hover {
  border-color: var(--brand);
}

.live-mark {
  background: var(--loss);
  border-radius: 999px;
  color: #fff;
  font-size: 0.75rem;
  font-weight: 700;
  padding: 0.15rem 0.5rem;
}

.live-faces {
  display: flex;
  gap: 0.25rem;
}

.live-faces img {
  border-radius: 0.3rem;
}

.live-versus {
  color: var(--dim);
  font-size: 0.85rem;
}

/* --- One day of matches, and the word of a match --------------------------- */

.day-head {
  align-items: baseline;
  border-bottom: var(--rule);
  display: flex;
  font-size: 0.9rem;
  gap: 0.6rem;
  justify-content: space-between;
  margin: 1.4rem 0 0.6rem;
  padding-bottom: 0.35rem;
}

.honour {
  color: var(--gold);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  margin: 0;
}

.versus {
  color: var(--dim);
  font-size: 0.75rem;
  margin: 0;
}

.versus img {
  border-radius: 0.2rem;
  margin-right: 0.25rem;
  vertical-align: -0.2rem;
}

.champion-search {
  margin-top: 0.75rem;
}

/* --- The tabs of a player -------------------------------------------------- */

/* A row of tabs sits on one rule. Each tab carries a border of three sides, and the
   tab of the page joins the surface under the row. */
.tabs {
  border-bottom: var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem;
  margin: 0.6rem 0 0.6rem;
}

.tab {
  background: var(--panel-2);
  border: var(--rule);
  border-bottom: none;
  border-radius: 0.35rem 0.35rem 0 0;
  color: var(--dim);
  font-size: 0.85rem;
  font-weight: 600;
  margin-bottom: -1px;
  padding: 0.35rem 0.8rem;
  text-decoration: none;
  white-space: nowrap;
}

.tab:hover {
  background: var(--panel);
  color: var(--ink);
}

.tab[aria-current='page'] {
  background: var(--void);
  border-top: 2px solid var(--brand);
  color: var(--ink);
  padding-top: calc(0.35rem - 1px);
}

.player-head {
  margin-bottom: 0.2rem;
}

.read-at {
  font-size: 0.8rem;
  margin: 0.2rem 0 0;
}

/* The games of every ranked queue of this season, over the rank cards. */
.season {
  margin: 0.6rem 0 0;
}

.season h2 {
  font-size: 0.95rem;
  margin: 0 0 0.3rem;
}

.season-queues {
  display: grid;
  gap: 0.35rem;
  list-style: none;
  margin: 0.4rem 0 0;
  padding: 0;
}

.season-queues li {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.season-queues .named {
  font-weight: 600;
  min-width: 7rem;
}

/* The mark of a player that this player plays with, in the list of a team. */
.premade {
  background: color-mix(in srgb, var(--brand) 22%, transparent);
  border-radius: 999px;
  color: var(--brand);
  font-size: 0.6rem;
  font-weight: 700;
  margin-left: 0.25rem;
  padding: 0 0.3rem;
}

/* The search of a player over the two tables of the Players tab. The field reads as
   one band of the page, in the shape of the toolbar of the champions. */
.player-search {
  align-items: center;
  background: var(--panel);
  border: var(--rule);
  border-radius: 0.4rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0.8rem 0;
  padding: 0.6rem 0.8rem;
}

.player-search label {
  font-weight: 600;
}

.player-search input {
  background: var(--void);
  flex: 1 1 16rem;
  padding: 0.45rem 0.6rem;
}

/* The change of the league points of one match, under the result of that match. */
.match-row .lp {
  font-size: 0.85rem;
  font-weight: 600;
}

/* The line of the gold and of the experience of one player, in a cell of a table. */
.minute-line {
  display: block;
  height: 28px;
  width: 120px;
}

.line-end {
  color: var(--dim);
  font-size: 0.72rem;
}

/* --- The rune pages of one match -------------------------------------------- */

.rune-cards {
  display: grid;
  gap: 0.8rem;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  margin-bottom: 1.2rem;
}

.rune-card {
  background: var(--panel);
  border: var(--rule);
  border-radius: 0.6rem;
  padding: 0.8rem;
}

.rune-card h2 {
  font-size: 0.95rem;
  margin: 0 0 0.6rem;
}

.rune-trees {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
}

.rune-tree h3 {
  align-items: center;
  color: var(--dim);
  display: flex;
  font-size: 0.78rem;
  font-weight: 600;
  gap: 0.3rem;
  margin: 0 0 0.35rem;
}

.rune-picks,
.shards {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.rune-picks li {
  align-items: center;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  max-width: 5rem;
  text-align: center;
}

.rune-picks span {
  color: var(--dim);
  font-size: 0.68rem;
  line-height: 1.2;
}

/* The keystone is the strongest rune of a page, and it stands out by its size. */
.rune-picks.with-keystone li:first-child span {
  color: var(--text);
}

.shards li {
  background: var(--panel-2);
  border: var(--rule);
  border-radius: 999px;
  font-size: 0.7rem;
  padding: 0.15rem 0.5rem;
}

/* --- The objectives of each side -------------------------------------------- */

.objectives th[scope='col'],
.objectives td {
  text-align: right;
}

.objectives th[scope='row'] {
  text-align: left;
  white-space: nowrap;
}

/* The bans stand at the end of the row, and the icons follow the numbers to the right. */
.objectives .ban-list {
  justify-content: flex-end;
}

.objectives .ban-list img {
  border-radius: 0.25rem;
}

.objectives {
  margin-bottom: 0.8rem;
}

.won-mark {
  color: var(--win);
  font-size: 0.75rem;
  font-weight: 700;
}

.free-mark {
  color: var(--gold);
  font-size: 0.7rem;
  font-weight: 700;
  margin: 0.2rem 0 0;
}

.grid + h2 {
  margin-top: 1.6rem;
}

/* --- The multi-search, and the rank inside a live game --------------------- */

textarea {
  background: var(--panel);
  border: var(--rule);
  border-radius: 0.4rem;
  color: inherit;
  font: inherit;
  padding: 0.5rem 0.6rem;
  resize: vertical;
  width: 100%;
}

.tier-mean {
  font-size: 0.8rem;
  font-weight: 400;
}

.more.secondary {
  font-size: 0.8rem;
  padding: 0.25rem 0.6rem;
}

/* --- The place of a player on the ladder, and the icon of a row ------------ */

.rank-place {
  color: var(--dim);
  font-size: 0.85rem;
  margin: 0.4rem 0 0;
}

.row-icon {
  border-radius: 0.25rem;
  vertical-align: -0.35rem;
}

.podium-card .row-icon {
  margin-right: 0.3rem;
}

.row-champions {
  display: inline-flex;
  gap: 0.2rem;
}

.row-champions img {
  border-radius: 0.25rem;
}

/* --- The league points over the time ---------------------------------------- */

.points {
  margin-bottom: 1rem;
}

.points h2 {
  font-size: 1.05rem;
  margin-bottom: 0.2rem;
}

.sparkline {
  color: var(--brand);
  display: block;
  height: 60px;
  max-width: 22rem;
  width: 100%;
}

.up {
  color: var(--win);
}

.down {
  color: var(--loss);
}

/* --- The grade of a champion of the tier list ------------------------------- */

.grade {
  border: var(--rule);
  border-radius: 0.3rem;
  display: inline-block;
  font-weight: 700;
  min-width: 2rem;
  padding: 0.1rem 0.3rem;
  text-align: center;
}

.grade-Splus {
  border-color: var(--challenger);
  color: var(--challenger);
}

.grade-S {
  border-color: var(--master);
  color: var(--master);
}

.grade-A {
  border-color: var(--diamond);
  color: var(--diamond);
}

.grade-B {
  border-color: var(--emerald);
  color: var(--emerald);
}

.grade-C {
  border-color: var(--silver);
  color: var(--silver);
}

.grade-D {
  border-color: var(--bronze);
  color: var(--bronze);
}

/* --- The build of a champion, and the pair of two champions ----------------- */

.build {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  margin-top: 1rem;
}

.build h3 {
  font-size: 0.9rem;
  margin-bottom: 0.4rem;
}

.matchup-list {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  list-style: none;
  padding: 0;
}

.matchup-list li {
  align-items: center;
  display: flex;
  gap: 0.5rem;
  justify-content: space-between;
}

.matchup-list a {
  align-items: center;
  display: flex;
  gap: 0.4rem;
  text-decoration: none;
}

.matchup-list img {
  border-radius: 0.25rem;
}

.pair {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
}

.pair-card {
  border: var(--rule);
  border-radius: 0.6rem;
  padding: 1rem;
  text-align: center;
}

.pair-card img {
  border-radius: 0.4rem;
}

.pair-card h2 {
  font-size: 1.15rem;
  margin: 0.4rem 0 0.2rem;
}

/* --- The figure of the five values of a player ------------------------------ */

.skills {
  margin-bottom: 1rem;
}

.skills h2 {
  font-size: 1.05rem;
  margin-bottom: 0.2rem;
}

.radar {
  color: var(--brand);
  display: block;
  height: 12rem;
  max-width: 12rem;
}

.radar text {
  fill: var(--dim);
  font-size: 0.6rem;
}

/* One list of bars under a heading needs room for that heading. */

.lanes {
  margin-bottom: 1rem;
}

.lanes + h2 {
  margin-top: 1.6rem;
}

/* --- The order of the abilities, the steps of a build, and the gold of a match --- */

.orders {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  list-style: none;
  padding: 0;
}

.orders li {
  align-items: center;
  display: flex;
  gap: 0.6rem;
}

.order {
  border: var(--rule);
  border-radius: 0.3rem;
  font-weight: 700;
  padding: 0.1rem 0.4rem;
}

.item-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  list-style: none;
  padding: 0;
}

.item-steps li {
  align-items: center;
  display: flex;
  gap: 0.4rem;
}

.gold-line {
  display: block;
  height: 9rem;
  max-width: 34rem;
  width: 100%;
}

/* The build path of an item, as a graph. The item stands at the root, and the parts of
 * one step stand under that step. A line joins a part to its result. */

.tree-scroll {
  overflow-x: auto;
  padding-bottom: 0.5rem;
}

/* `safe center` keeps the row centered, but lets the scroll reach a part that
 * overflows the start. Plain `center` centers a row wider than the screen, and
 * a browser never scrolls a start that overflows the origin, so a narrow screen
 * hides the left-most part with no way to reach it. */
.recipe-tree,
.recipe-tree ul {
  display: flex;
  justify-content: safe center;
  list-style: none;
  margin: 0;
  padding: 0;
}

.recipe-tree ul {
  padding-top: 1.2rem;
  position: relative;
}

/* The line that leaves a step and goes down to its parts. */

.recipe-tree ul::before {
  border-left: var(--rule);
  content: '';
  height: 1.2rem;
  left: 50%;
  position: absolute;
  top: 0;
  width: 0;
}

.recipe-tree li {
  padding: 1.2rem 0.4rem 0;
  position: relative;
  text-align: center;
}

/* The two halves of the line that joins one part to the step over it. */

.recipe-tree li::before,
.recipe-tree li::after {
  border-top: var(--rule);
  content: '';
  height: 1.2rem;
  position: absolute;
  right: 50%;
  top: 0;
  width: 50%;
}

.recipe-tree li::after {
  border-left: var(--rule);
  left: 50%;
  right: auto;
}

.recipe-tree li:first-child::before,
.recipe-tree li:last-child::after {
  border-top: 0;
}

.recipe-tree li:last-child::before {
  border-right: var(--rule);
}

/* The root of the graph, and a step with one part alone, need no line over the box. */

.recipe-tree li:only-child {
  padding-top: 0;
}

.recipe-tree li:only-child::before,
.recipe-tree li:only-child::after {
  display: none;
}

.recipe-tree img {
  border-radius: 0.25rem;
}

.tree-node {
  align-items: center;
  border: var(--rule);
  border-radius: 0.5rem;
  color: inherit;
  display: inline-flex;
  gap: 0.4rem;
  padding: 0.4rem 0.6rem;
  text-decoration: none;
  white-space: nowrap;
}

.tree-node:hover {
  border-color: var(--brand);
  color: var(--brand);
}

/* The mark of the free rotation. Every card holds the line, so the title of every card
 * of one row of the grid stands at the same height. */

.free-mark {
  min-height: 1.1rem;
}

/* The landing page holds a search of its own in the hero, but a reader who scrolls past
 * the hero still needs a way to search. The header search stays on every route, so the
 * navigation bar is the same component everywhere. */
