/* Arena Journey design system ("Journey 2"). Shared by every Journey page, the dashboard tabs and the Arena stats
   pages (champions, tier list, augments, items). Tokens, fonts and the theme live in tokens.css + themes/<name>.css
   (linked first). Component and motion reference: frontend/static/journey/README.md.

   Language: flat square panels with thin gold hairlines; craft lives in small ornaments (diamonds, corner brackets,
   fading rules, the octagonal Colosseum crest, the rune line; nothing spins). Type is the Beaufort serif at one weight with wide tracking for every title and
   number, and a humanist sans for body text and small letter-spaced caps labels. Red appears only on the logo, the one
   call to action, live states and crest cores. Motion animates transform and opacity only and stops under
   prefers-reduced-motion. Chromium 108 (League client): no color-mix(), no container style queries. */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  background: var(--j-black);
}

/* Scrollbars: the main site's red thumb (--j-scroll-*, tokens.css) on a dark track, thin and rounded, brightening on
   hover. Chromium (and the League client) draws the ::-webkit-scrollbar parts; Firefox, which has no such selector,
   gets scrollbar-color. Chromium 121+ drops the ::-webkit-scrollbar styling on any element with scrollbar-width or
   scrollbar-color set, so components never set those (only scrollbar-width: none to hide a bar). */
@supports not selector(::-webkit-scrollbar) {
  html {
    scrollbar-color: var(--j-scroll-thumb) var(--j-scroll-track);
  }

  .j-body * {
    scrollbar-width: thin;
  }
}

::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}

::-webkit-scrollbar-track {
  background: var(--j-scroll-track);
}

/* The 3px transparent border insets the thumb so it reads as a 6px rounded bar on the track. */
::-webkit-scrollbar-thumb {
  min-height: 40px;
  border: 3px solid transparent;
  border-radius: 999px;
  background: var(--j-scroll-thumb) padding-box;
}

::-webkit-scrollbar-thumb:hover {
  background-color: var(--j-scroll-thumb-hover);
}

::-webkit-scrollbar-thumb:active {
  background-color: var(--j-scroll-thumb-active);
}

::-webkit-scrollbar-corner {
  background: transparent;
}

/* Scroll areas inside the page: a slimmer bar on a clear track. */
.j-body *::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

.j-body *::-webkit-scrollbar-track {
  background: transparent;
}

.j-body *::-webkit-scrollbar-thumb {
  min-height: 28px;
  border-width: 2px;
}

body.j-body {
  position: relative;
  margin: 0;
  min-height: 100vh;
  background: var(--j-coal-950);
  color: var(--j-text);
  font-family: var(--j-body);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

:where(.j-body) a {
  color: inherit;
  text-decoration: none;
}

:where(.j-body) button,
:where(.j-body) input,
:where(.j-body) select {
  font: inherit;
  color: inherit;
}

:where(.j-body) img {
  display: block;
}

:where(.j-body) ::selection {
  background: rgba(var(--j-gold-rgb), 0.35);
  color: var(--j-gold-25);
}

.j-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.j-i {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Focus: a 1px gold outline 3px out plus a soft gold halo (every interactive component). */
:where(.j-body) :focus-visible {
  outline: 1px solid var(--j-gold-300);
  outline-offset: 3px;
  box-shadow: var(--j-focus-ring);
}

/* ---------- Page backdrop: per-page art, blurred and darkened, shaded and lit (core.js setBackdrop) ---------- */

.j-backdrop {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  background: var(--j-coal-950);
}

/* One layer per image; setBackdrop() stacks the next one on top and fades it in over 700ms, then drops the old one. */
.j-backdrop__art {
  position: absolute;
  inset: -24px;
  background-size: cover;
  background-position: center 22%;
  filter: var(--j-scene-filter);
  opacity: 0;
  transition: opacity 0.7s ease-in-out;
}

.j-backdrop__art.is-loaded {
  opacity: 1;
}

/* setBackdrop(url, {tone: 'mono'}): the official Arena art, turned to monochrome (--j-mono-filter). */
.j-backdrop__art--mono {
  filter: var(--j-mono-filter);
}


.j-backdrop__veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--j-scene-wash-top), var(--j-scene-shade);
}

/* Hero pages (the season landing): a lighter dim, a centred vignette and a coloured light wash at each corner. */
/* Optional ambient layer (setBackdrop(url, {ambient: true})): two soft coloured lights drifting slowly over the art.
   The art itself never moves: a moving blurred layer would be re-filtered every frame. The lights are plain
   gradients, rasterised once and only translated. */
.j-backdrop__light {
  position: absolute;
  inset: -25%;
  z-index: 2;
  display: none;
  background:
    radial-gradient(30% 26% at 30% 34%, rgba(var(--j-gold-rgb), 0.1), rgba(var(--j-gold-rgb), 0) 100%),
    radial-gradient(34% 30% at 70% 66%, rgba(var(--j-ember-rgb), 0.1), rgba(var(--j-ember-rgb), 0) 100%);
  will-change: transform;
}

.j-backdrop--ambient .j-backdrop__light {
  display: block;
  animation: j-ambient 36s ease-in-out infinite alternate;
}

@keyframes j-ambient {
  from { transform: translate3d(-6%, 3%, 0) rotate(-4deg); }
  to { transform: translate3d(6%, -3%, 0) rotate(4deg); }
}

.j-page-landing .j-backdrop__art {
  filter: var(--j-scene-filter-hero);
  background-position: center 30%;
}

.j-page-landing .j-backdrop__veil {
  background: var(--j-scene-wash-a), var(--j-scene-wash-b), var(--j-scene-shade-hero), rgba(var(--j-ink-rgb), 0.46);
}

/* Section art (Deep Dive sections, Wrap slides, page heroes): a sharp layer, a soft layer and a vignette, faded to the
   page colour at the top and bottom so stacked sections join. Markup: sceneHtml(url) in core.js. */
.j-scene {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.j-scene__art,
.j-scene__soft {
  position: absolute;
  inset: -20px;
  background-size: cover;
  background-position: center 25%;
}

.j-scene__art {
  filter: var(--j-scene-filter-section);
}

.j-scene__soft {
  filter: var(--j-scene-filter-soft);
  opacity: 0.7;
}

.j-scene::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, var(--j-coal-1000) 0%, rgba(var(--j-ink-rgb), 0) 16%, rgba(var(--j-ink-rgb), 0) 84%, var(--j-coal-1000) 100%),
    var(--j-scene-wash-a),
    var(--j-scene-wash-b),
    radial-gradient(95% 85% at 50% 45%, rgba(var(--j-ink-rgb), 0) 35%, rgba(var(--j-ink-rgb), 0.88) 100%);
}


.j-main {
  position: relative;
  z-index: 2;
}

/* ---------- Top bar (shared site header; layout and breakpoints in site/site.css) ---------- */

.j-topbar {
  position: relative;
  height: var(--j-bar-h);
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 20px;
  background: linear-gradient(180deg, rgba(var(--j-shadow-rgb), 0.96), rgba(var(--j-coal-900-rgb), 0.9));
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}

/* Bottom hairline, fading out at both ends. */
.j-topbar::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--j-rule-center);
  pointer-events: none;
}

/* The ArenaSweats logo exactly as on the leaderboard, with a small "PAGES" label under it. */
.j-brand {
  display: grid;
  justify-items: center;
  flex: none;
  padding: 2px 4px 0;
  line-height: 1;
  opacity: 0.95;
  transition: opacity var(--j-dur-fast) var(--j-ease-std);
}

.j-brand:hover {
  opacity: 1;
}

/* The leaderboard header logo (styles.css .logo-arena / .logo-sweats), scaled down: every length is in em of
   the real sizes (ARENA 64px, SWEATS 52px), so only font-size changes between breakpoints. font-synthesis: none
   keeps the single-weight faces from being faux-bolded by font-weight 800, exactly as on the leaderboard. */
.j-brand__word {
  display: flex;
  align-items: center;
}

.j-brand__arena,
.j-brand__sweats {
  font-weight: 800;
  font-synthesis: none;
  font-kerning: normal;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.j-brand__arena {
  font-family: "ArenaBrand", sans-serif;
  font-size: 26px;
  letter-spacing: 0.0390625em; /* 2.5px at 64px */
  background: linear-gradient(140deg, var(--j-logo-gold-edge), var(--j-logo-gold) 20%, var(--j-logo-gold-light) 50%, var(--j-logo-gold) 80%, var(--j-logo-gold-edge));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: 0.015625em 0.015625em 0.03125em var(--j-logo-shadow);
  -webkit-text-stroke: 0.0078125em var(--j-logo-gold-stroke); /* 0.5px at 64px */
}

.j-brand__sweats {
  display: inline-block;
  font-family: "HeyComic", sans-serif;
  font-size: 21.125px; /* 52/64 of ARENA */
  letter-spacing: 0.0192em; /* 1px at 52px */
  color: var(--j-logo-red);
  -webkit-text-stroke: 0.0192em var(--j-logo-red-stroke); /* 1px at 52px */
  animation: j-bounce 2.8s ease-in-out infinite;
}

/* The leaderboard logo's SWEATS bounce (4px at 52px). */
@keyframes j-bounce {
  0%, 100% { transform: translateY(0); text-shadow: 0.0192em 0.0192em 0.0385em var(--j-logo-shadow-soft); }
  50% { transform: translateY(-0.077em); text-shadow: 0.0192em 0.0577em 0.077em var(--j-logo-shadow); }
}

.j-brand__sub {
  margin-top: 3px;
  padding-left: 0.34em; /* optical centring of the tracked caps */
  font-family: var(--j-sans);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.34em;
  color: var(--j-ember-200);
}

.j-topbar__sep {
  width: 1px;
  height: 32px;
  flex: none;
  background: linear-gradient(180deg, rgba(var(--j-gold-rgb), 0), rgba(var(--j-gold-rgb), 0.55), rgba(var(--j-gold-rgb), 0));
}

.j-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  flex: 0 1 auto;
  color: var(--j-muted);
  font-size: 13px;
  transition: color var(--j-dur-fast) var(--j-ease-std);
}

.j-chip__gem {
  width: 18px;
  height: 20px;
  flex: none;
}

.j-chip__name {
  font-family: var(--j-display);
  font-size: 15px;
  letter-spacing: 0.04em;
  color: var(--j-gold-50);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color var(--j-dur-fast) var(--j-ease-std);
}

.j-chip:hover .j-chip__name {
  color: var(--j-white);
}

.j-chip__tag {
  white-space: nowrap;
}

.j-region-badge {
  padding: 1px 6px;
  border: 1px solid rgba(var(--j-ember-rgb), 0.35);
  color: var(--j-ember-200);
  font-family: var(--j-sans);
  font-size: 9.5px;
  font-weight: 400;
  letter-spacing: 0.18em;
}

.j-nav {
  display: flex;
  align-self: stretch;
  gap: 0;
}

/* Nav item: Beaufort tracked caps. The underline (a gold-to-cream glint) waits at half width and invisible, grows
   in on hover, and the active item adds a diamond pip on the bar's bottom edge. */
.j-nav__link {
  position: relative;
  display: flex;
  align-items: center;
  padding: 0 12px;
  font-family: var(--j-display);
  font-size: 12.5px;
  font-weight: 400;
  letter-spacing: var(--j-track-nav);
  text-transform: uppercase;
  color: var(--j-muted);
  white-space: nowrap;
  transition: color var(--j-dur-fast) var(--j-ease-std);
}

.j-nav__link::after {
  content: "";
  position: absolute;
  left: 6px;
  right: 6px;
  bottom: 0;
  height: 2px;
  background: var(--j-rule-glint);
  opacity: 0;
  transform: scaleX(0.5);
  transition: opacity var(--j-dur) var(--j-ease-std), transform var(--j-dur) var(--j-ease-std);
}

.j-nav__link:hover {
  color: var(--j-gold-100);
}

.j-nav__link:hover::after {
  opacity: 0.55;
  transform: none;
}

.j-nav__link.is-active {
  color: var(--j-gold-50);
}

.j-nav__link.is-active::after {
  opacity: 1;
  transform: none;
}

.j-nav__link.is-active::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -4px;
  z-index: 1;
  width: 8px;
  height: 8px;
  margin-left: -4px;
  border: 1px solid var(--j-gold-300);
  background: var(--j-gold-50);
  box-shadow: inset 0 0 0 1.5px var(--j-black), 0 0 8px rgba(var(--j-light-rgb), 0.55);
  transform: rotate(45deg);
}

.j-nav__link:focus-visible {
  outline-offset: -6px;
  box-shadow: none;
}

.j-topbar__right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

/* ---------- Buttons: gold outlines; one red call to action per page ---------- */

.j-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 36px;
  padding: 0 12px;
  border: 1px solid var(--j-line-control);
  border-radius: var(--j-radius-sm);
  background: rgba(var(--j-ink-rgb), 0.6);
  color: var(--j-gold-100);
  font-family: var(--j-sans);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: var(--j-track-meta);
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--j-dur-fast) var(--j-ease-std), border-color var(--j-dur-fast) var(--j-ease-std), background-color var(--j-dur-fast) var(--j-ease-std), box-shadow var(--j-dur) var(--j-ease-std);
}

.j-btn:hover {
  border-color: var(--j-gold-300);
  color: var(--j-gold-50);
}

.j-btn:active {
  background: rgba(var(--j-gold-rgb), 0.08);
}

.j-btn .j-i {
  width: 15px;
  height: 15px;
}

/* Gold accent: a brighter rim and a faint gold fill (secondary actions that deserve weight, e.g. Share in Wrap). */
.j-btn--ember {
  border-color: rgba(var(--j-gold-rgb), 0.55);
  background: linear-gradient(180deg, rgba(var(--j-gold-rgb), 0.14), rgba(var(--j-gold-rgb), 0.04));
  color: var(--j-gold-50);
}

.j-btn--ember:hover {
  border-color: var(--j-gold-200);
  box-shadow: 0 0 18px rgba(var(--j-gold-rgb), 0.2);
}

/* The red call to action (one per page: the header's ArenaSweats Leaderboard button). A crimson plate inside a thin
   gold rim; on hover the face warms, the rim brightens and one band of light crosses it. */
.j-btn--as {
  overflow: hidden;
  border-color: var(--j-cta-rim);
  background: var(--j-cta-face);
  box-shadow: var(--j-cta-lip);
  color: var(--j-white);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-shadow: 0 1px 1px rgba(var(--j-blood-rgb), 0.7);
}

.j-btn--as::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 40%;
  background: linear-gradient(90deg, rgba(var(--j-white-rgb), 0), rgba(var(--j-white-rgb), 0.22), rgba(var(--j-white-rgb), 0));
  opacity: 0;
  transform: translateX(-120%) skewX(-12deg);
  transition: transform var(--j-dur-slow) var(--j-ease-out), opacity var(--j-dur-slow) var(--j-ease-out);
  pointer-events: none;
}

.j-btn--as:hover {
  border-color: var(--j-cta-rim-hover);
  background: var(--j-cta-face-hover);
  box-shadow: var(--j-cta-lip), var(--j-cta-glow);
  color: var(--j-white);
}

.j-btn--as:hover::after {
  opacity: 1;
  transform: translateX(300%) skewX(-12deg);
}

.j-btn--sm {
  height: 30px;
  padding: 0 10px;
  font-size: 10.5px;
}

.j-btn.is-done {
  border-color: var(--j-up-color);
  color: var(--j-up-color);
}

/* ---------- Panels: flat, square, a 1px gold hairline ---------- */

.j-panel {
  position: relative;
  min-width: 0;
  padding: 14px 16px 16px;
  border: 1px solid var(--j-line);
  border-radius: var(--j-radius);
  background: var(--j-panel);
  box-shadow: var(--j-panel-shadow);
  animation: j-reveal 0.5s var(--j-ease-out) backwards;
  animation-delay: var(--d, 0s);
}

.j-panel--flush {
  padding: 0;
}

/* Framed panel (featured content, charts over art): a stronger hairline, a bright top rule inset 14px that fades at
   both ends, and the top-left and bottom-right corners cut at 45 degrees with a gold edge along each cut. Class name
   kept from the old gilded frame. */
.j-corners,
.j-frame {
  --cut: 18px;
  border-color: var(--j-line-mid);
  background: var(--j-panel-feature);
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
}

/* The gold cut edges: one stroke in each cut corner (a corner square whose 45 degree gradient is gold just inside the
   cut). Drawn on ::before, so the panel keeps its own background. */
.j-corners::before,
.j-frame::before {
  content: "";
  position: absolute;
  inset: -1px;
  z-index: 1;
  background:
    linear-gradient(135deg, rgba(var(--j-gold-rgb), 0) 50%, var(--j-gold-300) 50%, var(--j-gold-300) calc(50% + 2px), rgba(var(--j-gold-rgb), 0) calc(50% + 2px)) 0 0 / var(--cut) var(--cut) no-repeat,
    linear-gradient(315deg, rgba(var(--j-gold-rgb), 0) 50%, var(--j-gold-300) 50%, var(--j-gold-300) calc(50% + 2px), rgba(var(--j-gold-rgb), 0) calc(50% + 2px)) 100% 100% / var(--cut) var(--cut) no-repeat;
  pointer-events: none;
}

/* Corner marks on any box: add .j-brackets for a small solid gold triangle in the top-left and bottom-right corners,
   drawn from background layers, so the element keeps its own ::before/::after. */
.j-brackets {
  --bk: var(--j-bracket);
  --bk-size: 10px;
  background-image:
    linear-gradient(135deg, var(--bk) 50%, rgba(var(--j-gold-rgb), 0) 50%),
    linear-gradient(315deg, var(--bk) 50%, rgba(var(--j-gold-rgb), 0) 50%);
  background-repeat: no-repeat;
  background-size: var(--bk-size) var(--bk-size);
  background-position: 0 0, 100% 100%;
}

/* Beaufort Bold: the heavier display cut for section titles (the regular face is JourneyDisplay in tokens.css). */
@font-face {
  font-family: "JourneyDisplayBold";
  src: url("../tcg/fonts/BeaufortforLOL-Bold.ttf") format("truetype");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* Section header: a raised gunmetal nameplate sitting on a gold rail. The plate has a lit top bevel, a gold left edge
   and a blade end cut on the slant; a gold accent slash leads the heavy Beaufort caps, which are pressed into the plate
   (hard shadow under, faint light over). The rail runs from the plate's foot to the panel edge in solid gold metal,
   and counts in the meta sit on small raised gold-edged keys. */
/* The meta wraps under the title when the panel is too narrow for both on one line. */
.j-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 6px 0;
  min-height: 30px;
  margin-bottom: 16px;
}

.j-head__title {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  padding: 7px 30px 6px 12px;
  font-family: "JourneyDisplayBold", var(--j-display);
  font-size: 14.5px;
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--j-gold-50);
  text-shadow: 0 1px 0 rgba(var(--j-shadow-rgb), 0.95), 0 -1px 0 rgba(var(--j-light-rgb), 0.08);
  background:
    linear-gradient(90deg, var(--j-gold-300), var(--j-gold-500)) 0 0 / 2px 100% no-repeat,
    linear-gradient(180deg, rgba(var(--j-light-rgb), 0.1), rgba(var(--j-light-rgb), 0) 45%),
    linear-gradient(180deg, var(--j-coal-600) 0%, var(--j-coal-700) 48%, var(--j-coal-850, var(--j-coal-800)) 100%);
  box-shadow: inset 0 1px 0 rgba(var(--j-light-rgb), 0.22), inset 0 -1px 0 rgba(var(--j-shadow-rgb), 0.6);
  clip-path: polygon(0 0, calc(100% - 18px) 0, 100% 100%, 0 100%);
  white-space: nowrap;
}

/* The accent slash: two gold blades leaning forward. */
.j-head__title::before {
  content: "";
  width: 11px;
  height: 14px;
  flex: none;
  background:
    linear-gradient(180deg, var(--j-gold-100), var(--j-gold-400)) 0 0 / 4px 100% no-repeat,
    linear-gradient(180deg, var(--j-gold-300), var(--j-gold-600)) 7px 0 / 3px 100% no-repeat;
  transform: skewX(-24deg);
  filter: drop-shadow(0 0 4px rgba(var(--j-gold-rgb), 0.45));
}

/* The rail: a lit gold edge over a dark lip, from the plate's foot to the panel edge. */
.j-head__rule {
  flex: 1;
  align-self: flex-end;
  height: 3px;
  min-width: 24px;
  margin-left: -18px;
  background:
    linear-gradient(90deg, var(--j-gold-200), var(--j-gold-400) 30%, var(--j-gold-600)) 0 0 / 100% 2px no-repeat,
    linear-gradient(rgba(var(--j-shadow-rgb), 0.7), rgba(var(--j-shadow-rgb), 0.7)) 0 2px / 100% 1px no-repeat;
}

.j-head__meta {
  display: flex;
  align-self: center;
  align-items: center;
  gap: 14px;
  margin-left: 16px;
  font-family: var(--j-sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--j-muted);
  white-space: nowrap;
}

/* Counts on a small raised key. */
.j-head__meta b {
  display: inline-block;
  margin: 0 5px;
  padding: 2px 7px 1px;
  border-radius: 3px;
  font-family: "JourneyDisplayBold", var(--j-display);
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 0.03em;
  color: var(--j-gold-100);
  background: linear-gradient(180deg, var(--j-coal-600), var(--j-coal-800));
  box-shadow: inset 0 0 0 1px rgba(var(--j-gold-rgb), 0.55), inset 0 1px 0 rgba(var(--j-light-rgb), 0.2), 0 2px 0 rgba(var(--j-gold-rgb), 0.3), 0 3px 5px rgba(var(--j-shadow-rgb), 0.6);
}

/* Big section title (page sections, Deep Dive chapters): kicker, Beaufort title and a short gold rule. */
.j-title {
  margin: 0;
  font-family: var(--j-display);
  font-size: clamp(30px, 4vw, 52px);
  font-weight: 400;
  line-height: 1.05;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--j-gold-50);
}

.j-title-rule {
  display: block;
  width: 56px;
  height: 1px;
  margin: 14px 0;
  background: var(--j-rule);
}

/* ---------- Ornaments ---------- */

/* Inline separator between meta items: a small gold diamond (never a dot). Class name kept. */
.j-diamond {
  display: inline-block;
  width: 5px;
  height: 5px;
  flex: none;
  vertical-align: 0.15em;
  background: var(--j-gold-300);
  transform: rotate(45deg);
}

.j-diamond--solid {
  background: var(--j-gold-300);
}

/* "You" marker: a small glowing diamond in the secondary light. */
.j-diamond--ember {
  width: 7px;
  height: 7px;
  vertical-align: 0.05em;
  background: linear-gradient(135deg, var(--j-ember-100), var(--j-ember-300) 45%, var(--j-ember-500));
  box-shadow: 0 0 8px rgba(var(--j-ember-rgb), 0.7);
}

/* Diamond pip: a rotated square outline (--size), optionally breathing (.j-breathe) or filled (--fill). */
.j-pip {
  --size: 7px;
  display: inline-block;
  width: var(--size);
  height: var(--size);
  flex: none;
  border: 1px solid var(--j-gold-300);
  transform: rotate(45deg);
}

.j-pip--fill {
  background: var(--j-gold-300);
}

.j-pip--core {
  background: var(--j-gold-50);
  box-shadow: inset 0 0 0 1.5px var(--j-black), 0 0 8px rgba(var(--j-light-rgb), 0.55);
}

/* ArenaSweats seal: our own octagon mark (beside their diamond). A chamfered gold frame
   holding an icon, used for door badges and level plates. */
.j-seal {
  --size: 52px;
  position: relative;
  display: grid;
  place-items: center;
  width: var(--size);
  height: var(--size);
  flex: none;
  color: var(--j-gold-100);
  clip-path: polygon(29% 0, 71% 0, 100% 29%, 100% 71%, 71% 100%, 29% 100%, 0 71%, 0 29%);
  background: rgba(var(--j-gold-rgb), 0.75);
}

.j-seal::before {
  content: "";
  position: absolute;
  inset: 1px;
  clip-path: inherit;
  background: radial-gradient(circle at 50% 35%, rgba(var(--j-coal-700-rgb), 0.95), rgba(var(--j-ink-rgb), 0.95) 70%);
}

.j-seal > * {
  position: relative;
}

.j-seal .j-i {
  width: 40%;
  height: 40%;
}

/* Rule ornament: a centred line with a small diamond, for dividing hero content. */
.j-rule {
  display: flex;
  align-items: center;
  gap: 10px;
  width: min(320px, 70%);
  margin: 0 auto;
}

.j-rule::before,
.j-rule::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, rgba(var(--j-gold-rgb), 0), rgba(var(--j-gold-rgb), 0.5));
}

.j-rule::after {
  background: linear-gradient(90deg, rgba(var(--j-gold-rgb), 0.5), rgba(var(--j-gold-rgb), 0));
}

/* ---------- Text and stat blocks ---------- */

.j-label {
  font-family: var(--j-sans);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: var(--j-track-label);
  text-transform: uppercase;
  color: var(--j-muted);
}

.j-kicker {
  font-family: var(--j-sans);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: var(--j-track-head);
  text-transform: uppercase;
  color: var(--j-gold-300);
}

.j-num {
  font-family: var(--j-display);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}

.j-stat {
  display: flex;
  flex-direction: column-reverse;
  justify-content: flex-end;
  gap: 2px;
  min-width: 0;
  margin: 0;
}

.j-stat__value {
  margin: 0;
  font-family: var(--j-display);
  font-size: 22px;
  font-weight: 400;
  line-height: 1.1;
  color: var(--j-gold-50);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.j-stat__value small {
  margin-left: 6px;
  font-family: var(--j-sans);
  font-size: 10.5px;
  letter-spacing: var(--j-track-label);
  color: var(--j-muted);
  text-transform: uppercase;
}

.j-stat__label {
  font-family: var(--j-sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: var(--j-track-label);
  text-transform: uppercase;
  color: var(--j-text-2);
}

.j-stat__note {
  font-size: 11.5px;
  letter-spacing: 0.06em;
  color: var(--j-muted);
  text-transform: uppercase;
}

.j-stat--xl .j-stat__value {
  font-size: 40px;
}

.j-stat--gold .j-stat__value { color: var(--j-gold-300); }
.j-stat--prism .j-stat__value { color: var(--j-p1); text-shadow: 0 0 18px rgba(var(--j-p1-rgb), 0.25); }
.j-stat--ember .j-stat__value { color: var(--j-ember-200); }
.j-stat--rose .j-stat__value { color: var(--j-rose); }

/* Stat columns: values over labels separated by hairline left borders (headers, hero facts). Wrap .j-stat in .j-stats. */
.j-stats {
  display: flex;
  flex-wrap: wrap;
  row-gap: 8px;
  margin: 0;
}

.j-stats > .j-stat {
  flex: 1 1 96px;
  min-width: 96px;
  padding: 2px 18px;
  border-left: 1px solid var(--j-line-divider);
}

.j-up { color: var(--j-up-color); }
.j-down { color: var(--j-rose); }

/* Placement ordinal: "1st" with a small suffix, tinted by finish. */
/* Placement ordinal: the number with its suffix tight against it as a raised small-caps superscript (1ST). The number
   uses proportional figures: tabular figures give a "1" wide side bearings that pushed the suffix away. */
.j-ord {
  display: inline-flex;
  align-items: flex-start;
  font-family: var(--j-display);
  font-weight: 400;
  line-height: 1;
  font-variant-numeric: proportional-nums;
  white-space: nowrap;
  gap: 0 !important; /* parents' "span { gap }" rules must not split the number from its suffix */
}

.j-ord small {
  display: inline;
  margin: 0.12em 0 0 0.01em;
  font-size: 0.52em;
  line-height: 1;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* 1st is prismatic: the iridescent gradient clipped to the text, lilac as the fallback colour. The glow is a drop-shadow
   (a text-shadow would paint over the clipped gradient). */
.j-ord--1 {
  color: var(--j-p1);
  background: var(--j-text-1);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 0 6px rgba(var(--j-p1-rgb), 0.35));
}

.j-ord--2,
.j-ord--3 { color: var(--j-p2); }
.j-ord--4 { color: var(--j-p4); }
.j-ord--5,
.j-ord--6 { color: var(--j-p5); }

/* Augment grade (core.js gradeChip): the letter on a flat metal plate, like the Arena pages' tier plates.
   S prismatic, A gold, B silver, C bronze, D to F rust. */
.j-grade {
  --gc: var(--j-p4);
  --gc-rgb: var(--j-p4-rgb);
  display: inline-grid;
  place-items: center;
  min-width: 26px;
  height: 22px;
  padding: 0 4px;
  border: 1px solid rgba(var(--gc-rgb), 0.7);
  background: linear-gradient(180deg, rgba(var(--gc-rgb), 0.24), rgba(var(--gc-rgb), 0.06));
  font-family: var(--j-display);
  font-size: 12.5px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--gc);
  white-space: nowrap;
  cursor: default;
}

.j-grade--lg {
  min-width: 40px;
  height: 34px;
  padding: 0 7px;
  font-size: 19px;
}

.j-grade--s { --gc: var(--j-p1); --gc-rgb: var(--j-p1-rgb); box-shadow: 0 0 10px rgba(var(--j-p1-rgb), 0.3); text-shadow: 0 0 8px rgba(var(--j-p1-rgb), 0.55); }
.j-grade--a { --gc: var(--j-p2); --gc-rgb: var(--j-p2-rgb); }
.j-grade--b { --gc: var(--j-silver-100); --gc-rgb: var(--j-silver-rgb); }
.j-grade--c { --gc: var(--j-bronze-light); --gc-rgb: var(--j-bronze-rgb); }
.j-grade--d,
.j-grade--e,
.j-grade--f { --gc: var(--j-rust-light); --gc-rgb: var(--j-rust-rgb); }

/* Filled swatch for a placement (bars, legend squares, calendar cells): bar shading over a flat two-stop fill. */
.j-fill-1 { background: var(--j-gloss), var(--j-fill-1); }
.j-fill-2,
.j-fill-3 { background: var(--j-gloss), var(--j-fill-2); }
.j-fill-4 { background: var(--j-gloss), var(--j-fill-4); }
.j-fill-5,
.j-fill-6 { background: var(--j-gloss), var(--j-fill-5); }

.j-legend {
  display: flex;
  gap: 14px;
  align-items: center;
}

.j-legend__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--j-sans);
  font-size: 10px;
  letter-spacing: var(--j-track-meta);
  text-transform: uppercase;
  color: var(--j-muted);
}

.j-legend__swatch {
  width: 9px;
  height: 9px;
  transform: rotate(45deg) scale(0.85);
}

/* ---------- Frames ---------- */

/* Square icon frame with a gold edge (class kept from the old hexagon); put an <img> inside. */
.j-hex {
  --size: 40px;
  --edge: rgba(var(--j-gold-rgb), 0.6);
  position: relative;
  width: var(--size);
  height: var(--size);
  flex: none;
  padding: 1px;
  background: var(--edge);
}

.j-hex > * {
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: var(--j-coal-900);
}

.j-hex--prism { --edge: var(--j-fill-prismatic); }
.j-hex--ember { --edge: linear-gradient(160deg, var(--j-ember-100), var(--j-ember-500) 55%, var(--j-ember-300)); }
.j-hex--dim { --edge: rgba(var(--j-stone-rgb), 0.35); }

/* Icon badge: a rotated square with a gold rim and a soft gold halo, holding an icon upright (class kept from the
   round medallion it replaced). */
.j-gem {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--size, 52px);
  height: var(--size, 52px);
  flex: none;
}

.j-gem::before {
  content: "";
  position: absolute;
  inset: 14.6%;
  border: 1px solid rgba(var(--j-gold-rgb), 0.75);
  background: rgba(var(--j-ink-rgb), 0.85);
  box-shadow: 0 0 24px rgba(var(--j-gold-rgb), 0.18);
  transform: rotate(45deg);
  transition: box-shadow var(--j-dur) var(--j-ease-std);
}

.j-gem > * {
  position: relative;
}

.j-gem .j-i {
  width: 34%;
  height: 34%;
  color: var(--j-gold-100);
  stroke-width: 1.5;
}

/* Animated metal frame for portraits and icons: gold and silver carry a slow sheen, prismatic scrolls. */
.j-mframe {
  --mframe-metal: linear-gradient(135deg, var(--j-gold-200), var(--j-gold-400) 50%, var(--j-gold-600));
  border: 2px solid transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box, border-box;
  background-image: linear-gradient(var(--j-coal-900), var(--j-coal-900)), var(--mframe-sheen, linear-gradient(transparent, transparent)), var(--mframe-metal);
  background-repeat: no-repeat, repeat-x, no-repeat;
}

.j-mframe--gold,
.j-mframe--silver {
  --mframe-sheen: linear-gradient(100deg, rgba(var(--j-white-rgb), 0) 30%, rgba(var(--j-white-rgb), 0.55) 50%, rgba(var(--j-white-rgb), 0) 70%);
  background-size: auto, 200% 100%, auto;
  animation: j-mframe-sheen 5s linear infinite;
}

.j-mframe--silver {
  --mframe-metal: linear-gradient(135deg, var(--j-silver-100), var(--j-silver-500) 50%, var(--j-silver-700));
}

.j-mframe--prismatic {
  --mframe-metal: var(--j-fill-prismatic);
  background-size: auto, auto, 200% 100%;
  background-repeat: no-repeat, no-repeat, repeat-x;
  animation: j-mframe-prism 6s linear infinite;
}

@keyframes j-mframe-sheen { from { background-position: 0 0, 100% 0, 0 0; } to { background-position: 0 0, -100% 0, 0 0; } }
@keyframes j-mframe-prism { from { background-position: 0 0, 0 0, 0 0; } to { background-position: 0 0, 0 0, -200% 0; } }

/* Champion / item / augment icons. */
.j-icon {
  width: var(--size, 28px);
  height: var(--size, 28px);
  flex: none;
  object-fit: cover;
  border-radius: 0;
  background: var(--j-coal-900);
  border: 1px solid rgba(var(--j-gold-rgb), 0.3);
}

.j-icon--round {
  border-radius: 50%;
  border-color: rgba(var(--j-gold-rgb), 0.35);
}

.j-icon--prismatic { border-color: rgba(var(--j-prism-rgb), 0.85); box-shadow: 0 0 7px rgba(var(--j-prism-rgb), 0.35); }
.j-icon--gold { border-color: rgba(var(--j-gold-200-rgb), 0.85); }
.j-icon--silver { border-color: rgba(var(--j-silver-rgb), 0.6); }

.j-icon--empty {
  border-style: dashed;
  border-color: rgba(var(--j-gold-rgb), 0.16);
  background: rgba(var(--j-shadow-rgb), 0.25);
}

/* ---------- Honeycomb icon grid (core.js renderHoneycomb) ---------- */
/* Pointy-top hexagons (height = width x 1.1547), alternate rows offset by half a cell, rows overlapped by
   h/4 - gap x 0.866. Each cell: a metal frame and the icon, both clipped to the hexagon. Cells ripple in from the
   centre (55ms per ring); hover lifts a cell. */

.j-hc {
  --w: 54px;
  --gap: 5px;
  --h: calc(var(--w) * 1.1547);
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 6px 0;
}

.j-hc::before {
  content: "";
  position: absolute;
  inset: 8% 12%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(var(--j-gold-rgb), 0.14), rgba(var(--j-gold-rgb), 0.04) 55%, rgba(var(--j-gold-rgb), 0));
  filter: blur(30px);
  pointer-events: none;
}

.j-hc__row {
  display: flex;
  gap: var(--gap);
}

.j-hc__row + .j-hc__row {
  margin-top: calc(var(--gap) * 0.866 - var(--h) / 4);
}

.j-hc__cell {
  --t: 2px;
  --hc-metal: linear-gradient(160deg, var(--j-silver-200), var(--j-silver-500) 50%, var(--j-silver-700));
  position: relative;
  flex: none;
  width: var(--w);
  height: var(--h);
  transition: transform 0.2s var(--j-ease-out), filter 0.2s var(--j-ease-out);
  animation: j-cell-in 0.46s var(--j-ease-cell) backwards;
  animation-delay: var(--d, 0s);
}

.j-hc.is-settled .j-hc__cell {
  animation: none;
}

.j-hc__cell:hover,
.j-hc__cell:focus-visible {
  z-index: 1;
  outline: none;
  box-shadow: none;
  transform: scale(1.18);
}

.j-hc__frame,
.j-hc__face {
  position: absolute;
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
}

.j-hc__frame {
  inset: 0;
  background: var(--hc-metal);
}

.j-hc__face {
  inset: calc(var(--t) * 1.1547) var(--t);
  overflow: hidden;
  background: var(--j-coal-900);
}

.j-hc__face img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.12);
}

.j-hc__face::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(160deg, rgba(var(--j-white-rgb), 0.18), rgba(var(--j-white-rgb), 0) 38%);
}

.j-hc__cell--first { --t: 4px; --hc-metal: var(--j-edge-1); }
.j-hc__cell--won { --t: 3px; --hc-metal: var(--j-edge-2); }
.j-hc__cell--played { --t: 2px; --hc-metal: var(--j-edge-4); }
.j-hc__cell--none { --t: 1px; --hc-metal: rgba(var(--j-stone-rgb), 0.3); }
.j-hc__cell--prismatic { --t: 3px; --hc-metal: var(--j-fill-prismatic); }
.j-hc__cell--none img { opacity: 0.3; filter: brightness(0.7) grayscale(1); }

/* The glow is a filter, so it is kept to the hovered cell (a comb can hold 500 cells); the comb's soft light comes
   from .j-hc::before. */
.j-hc__cell:hover,
.j-hc__cell:focus-visible {
  filter: brightness(1.25) drop-shadow(0 0 12px rgba(var(--j-p1-rgb), 0.5));
}

@keyframes j-cell-in {
  from { opacity: 0; transform: translateY(8px) scale(0.7); }
}

/* ---------- Badge banners (core.js banner / bannerImg) ---------- */
/* The badges are hanging banners (207 x 304). A banner unfurls from its rod on entry (.7s), an owned one sways on it
   (the profile badge detail's 6s rotateY swing, gentler), a light crosses it on hover and it lifts 4px; a soft shadow
   pools under it. In-progress and locked banners stay still and dimmed. Transform and opacity only; the shine is a
   background pass on hover. The empty .j-banner__trim layer and [data-prestige] are for prestige trims. */

.j-banner-img {
  display: block;
  height: auto;
  aspect-ratio: 207 / 304;
  object-fit: contain;
}

/* Width: --bw when a stylesheet sets it, else the width banner() was given (--bw0, inline). */
.j-banner {
  position: relative;
  display: inline-block;
  flex: none;
  width: var(--bw, var(--bw0));
  aspect-ratio: 207 / 304;
  isolation: isolate;
  transform-origin: 50% 0;
  transition: transform var(--j-dur) var(--j-ease-out);
  animation: j-banner-in 0.7s var(--j-ease) backwards;
  animation-delay: var(--d, 0ms);
}

/* The shadow pooled under the banner (static, so nothing filtered moves). */
.j-banner::before {
  content: "";
  position: absolute;
  left: 8%;
  right: 8%;
  bottom: -9%;
  height: 14%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(var(--j-shadow-rgb), 0.7), rgba(var(--j-shadow-rgb), 0));
  pointer-events: none;
}

.j-banner--owned::after {
  content: "";
  position: absolute;
  inset: -14% -30% 0;
  z-index: -1;
  background: radial-gradient(closest-side, rgba(var(--j-gold-rgb), 0.24), rgba(var(--j-gold-rgb), 0));
  pointer-events: none;
}

.j-banner__sway {
  position: absolute;
  inset: 0;
  transform-origin: 50% 0;
}

.j-banner--owned .j-banner__sway {
  animation: j-banner-sway 6s ease-in-out infinite;
  animation-delay: calc(var(--d, 0ms) * -7);
}

.j-banner .j-banner-img {
  width: 100%;
}

.j-banner--near .j-banner-img {
  opacity: 0.6;
  filter: grayscale(0.75) brightness(0.85);
}

.j-banner--locked .j-banner-img {
  opacity: 0.35;
  filter: grayscale(1) brightness(0.7);
}

.j-banner__shine,
.j-banner__trim {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.j-banner__shine {
  background: linear-gradient(105deg, rgba(var(--j-white-rgb), 0) 40%, rgba(var(--j-white-rgb), 0.55) 50%, rgba(var(--j-white-rgb), 0) 60%) 120% 0 / 260% 100% no-repeat;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  opacity: 0;
}

:where(a, button, [tabindex], .j-hc__cell):hover .j-banner,
.j-banner:hover {
  transform: translateY(-4px);
}

:where(a, button, [tabindex], .j-hc__cell):hover .j-banner__shine,
.j-banner:hover .j-banner__shine {
  opacity: 1;
  animation: j-banner-shine 0.9s var(--j-ease-out) both;
}

@keyframes j-banner-in {
  from { opacity: 0; transform: translateY(-10px) scaleY(0.4); }
}

@keyframes j-banner-sway {
  0%, 100% { transform: perspective(calc(var(--bw, var(--bw0)) * 2.4)) rotateY(-11deg); }
  50% { transform: perspective(calc(var(--bw, var(--bw0)) * 2.4)) rotateY(11deg); }
}

@keyframes j-banner-shine {
  from { background-position: 120% 0; }
  to { background-position: -20% 0; }
}

/* ---------- Segmented filters and selects ---------- */

.j-segs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.j-seg {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 30px;
  padding: 0 11px;
  border: 1px solid rgba(var(--j-gold-rgb), 0.22);
  border-radius: var(--j-radius-sm);
  background: rgba(var(--j-ink-rgb), 0.5);
  color: var(--j-muted);
  font-family: var(--j-sans);
  font-size: 10.5px;
  font-weight: 400;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--j-dur-fast) var(--j-ease-std), border-color var(--j-dur-fast) var(--j-ease-std), background-color var(--j-dur-fast) var(--j-ease-std);
}

.j-seg b {
  font-family: var(--j-display);
  font-weight: 400;
  font-size: 12.5px;
  letter-spacing: 0.02em;
  color: var(--j-dim);
  transition: color var(--j-dur-fast) var(--j-ease-std);
}

.j-seg:hover {
  border-color: var(--j-line-strong);
  color: var(--j-gold-100);
}

.j-seg.is-active {
  border-color: var(--j-gold-300);
  background: rgba(var(--j-gold-rgb), 0.12);
  color: var(--j-gold-50);
}

.j-seg.is-active b {
  color: var(--j-gold-200);
}

.j-select {
  position: relative;
  display: inline-flex;
}

.j-select select {
  height: 30px;
  padding: 0 32px 0 11px;
  border: 1px solid var(--j-line-control);
  border-radius: var(--j-radius-sm);
  background: rgba(var(--j-ink-rgb), 0.6);
  color: var(--j-gold-100);
  font-family: var(--j-sans);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  appearance: none;
  cursor: pointer;
  transition: border-color var(--j-dur-fast) var(--j-ease-std);
}

.j-select select:hover,
.j-select select:focus {
  border-color: var(--j-gold-300);
}

.j-select select option {
  background: var(--j-coal-850);
  text-transform: none;
}

.j-select .j-i {
  position: absolute;
  right: 10px;
  top: 50%;
  margin-top: -7px;
  width: 14px;
  height: 14px;
  pointer-events: none;
  color: var(--j-gold-300);
}

/* ---------- Rows and bars ---------- */

/* Hoverable list row: a faint gold wash and a 2px gold left edge that grows in. */
.j-row {
  position: relative;
  transition: background-color var(--j-dur-fast) var(--j-ease-std);
}

.j-row::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--j-gold-300);
  transform: scaleY(0);
  transition: transform var(--j-dur) var(--j-ease-std);
}

.j-row:hover {
  background-color: rgba(var(--j-gold-rgb), 0.05);
}

.j-row:hover::before,
.j-row.is-selected::before {
  transform: none;
}

.j-track {
  position: relative;
  height: 8px;
  background: rgba(var(--j-white-rgb), 0.06);
  overflow: hidden;
}

.j-track__fill {
  position: absolute;
  inset: 0 auto 0 0;
  box-shadow: var(--j-bar-edge);
  transform-origin: left;
  animation: j-grow 0.9s var(--j-ease) both;
}

/* ---------- Twitch glyph and links (story-kit.js twitchGlyph, twitchLinks; shared with the dashboard) ---------- */
.j-twitch {
  flex: none;
  fill: var(--j-twitch);
  vertical-align: -2px;
}

.j-twitch-links {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 8px 10px;
}

.j-twitch-link {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 11px;
  border: 1px solid rgba(var(--j-twitch-rgb), 0.5);
  background: rgba(var(--j-twitch-rgb), 0.1);
  color: var(--j-text);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-decoration: none;
  transition: border-color var(--j-dur-fast) var(--j-ease-std), background-color var(--j-dur-fast) var(--j-ease-std);
}

.j-twitch-link:hover {
  border-color: var(--j-twitch);
  background: rgba(var(--j-twitch-rgb), 0.2);
}

/* ---------- Tooltip (core.js installTooltips) ---------- */

.j-tip {
  position: fixed;
  z-index: 100;
  max-width: 280px;
  padding: 8px 11px;
  border: 1px solid rgba(var(--j-gold-rgb), 0.45);
  background: rgba(var(--j-coal-900-rgb), 0.95);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  box-shadow: 0 8px 24px rgba(var(--j-shadow-rgb), 0.55);
  color: var(--j-text);
  font-size: 12.5px;
  line-height: 1.45;
  pointer-events: none;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity var(--j-dur-fast) var(--j-ease-std), transform var(--j-dur-fast) var(--j-ease-std);
}

.j-tip.is-on {
  opacity: 1;
  transform: none;
}

.j-tip b {
  font-family: var(--j-display);
  font-weight: 400;
  font-size: 13.5px;
  letter-spacing: 0.04em;
  color: var(--j-gold-100);
}

/* A tip that opens with a bold name ("<b>Skillshots Dodged</b>Miss Fortune, 12 Oct") puts the name on its own line. */
.j-tip > b:first-child {
  display: block;
  margin-bottom: 2px;
}

.j-tip small {
  display: block;
  margin-top: 3px;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--j-muted);
}

/* Stat tooltips (story-kit.js statTip for honeycomb cells, the rating chart's day tips, the champion pages' tier
   honeycombs): the name on its own line, then value + label pairs with room between them, or label / value rows. */
.j-tip .j-tip__name {
  display: block;
  margin-bottom: 5px;
  font-size: 15px;
  line-height: 1.25;
}

.j-tip__stats {
  display: flex;
  flex-wrap: wrap;
  gap: 3px 14px;
  font-size: 12.5px;
  color: var(--j-text-2);
}

.j-tip__stats > span { white-space: nowrap; }

.j-tip .j-tip__stats b,
.j-tip .j-tip__row b {
  margin-right: 2px;
  font-size: 14px;
  letter-spacing: 0.02em;
  color: var(--j-gold-50);
}

.j-tip__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 20px;
  padding: 2px 0;
  font-size: 12.5px;
  color: var(--j-text-2);
}

.j-tip .j-tip__row b.is-up { color: var(--j-up-color); }
.j-tip .j-tip__row b.is-down { color: var(--j-rose); }

/* ---------- Loader: the ArenaSweats rune line ---------- */
/* A gold rule set with diamonds. A light runs along it once per beat (2.4s), filling the rule behind it and igniting
   each diamond as it passes; the lit diamonds cool while the next pass gathers. The full loader puts the ArenaSweats
   wordmark above it with a light sweeping across the letters in time with the rule. Sizes: .j-rune--md (panels
   and tab switches) and --lg (the full loader). Transform and opacity only, apart from the
   wordmark shine (a background pass over two words). Under reduced motion it stands still: the rule filled, the
   diamonds lit. seasonLoader(root) builds the full loader, loading(label) the panel one, runeLine(size) the bare
   line. */

.j-rune {
  --w: 168px;
  --gem: 8px;
  --dur: 2.4s;
  position: relative;
  flex: none;
  width: var(--w);
  max-width: 100%;
  height: calc(var(--gem) * 3);
}

.j-rune--lg { --w: min(300px, 72vw); --gem: 10px; }

.j-rune > i {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  pointer-events: none;
}

.j-rune__rule {
  height: 1px;
  margin-top: -0.5px;
  background: linear-gradient(90deg, rgba(var(--j-gold-rgb), 0), rgba(var(--j-gold-rgb), 0.3) 14%, rgba(var(--j-gold-rgb), 0.3) 86%, rgba(var(--j-gold-rgb), 0));
}

/* The filled part of the rule: grows with the light, then fades so the next pass starts clean. */
.j-rune__fill {
  height: 1px;
  margin-top: -0.5px;
  background: linear-gradient(90deg, rgba(var(--j-gold-rgb), 0), var(--j-gold-400) 18%, var(--j-gold-200) 82%, var(--j-gold-100));
  transform-origin: 0 50%;
  animation: j-rune-fill var(--dur) linear infinite;
}

/* The running light: a long thin streak with a cream core, centred on the fill's head. */
.j-rune__glint {
  height: calc(var(--gem) * 3);
  margin-top: calc(var(--gem) * -1.5);
  background:
    radial-gradient(closest-side, rgba(var(--j-white-rgb), 0.95), rgba(var(--j-gold-rgb), 0.55) 40%, rgba(var(--j-gold-rgb), 0)) 50% 50% / calc(var(--gem) * 2.2) calc(var(--gem) * 1.4) no-repeat,
    radial-gradient(closest-side, rgba(var(--j-gold-rgb), 0.5), rgba(var(--j-gold-rgb), 0)) 50% 50% / calc(var(--gem) * 9) calc(var(--gem) * 0.7) no-repeat;
  animation: j-rune-run var(--dur) linear infinite;
}

/* Diamonds sit on the rule at --p (0 to 1 of its width); --s scales one (the centre diamond is larger). */
.j-rune > b {
  --s: 1;
  position: absolute;
  top: 50%;
  left: calc(var(--p) * 100%);
  width: calc(var(--gem) * var(--s));
  height: calc(var(--gem) * var(--s));
  margin: calc(var(--gem) * var(--s) * -0.5) 0 0 calc(var(--gem) * var(--s) * -0.5);
  border: 1px solid rgba(var(--j-gold-rgb), 0.55);
  background: var(--j-coal-950);
  rotate: 45deg;
  animation: j-rune-pulse var(--dur) var(--j-ease-out) infinite;
  /* The light reaches --p at 72% of --p through the beat; each diamond peaks just after. */
  animation-delay: calc(var(--dur) * var(--p) * 0.72 - var(--dur) * 0.02);
}

.j-rune > b::after {
  content: "";
  position: absolute;
  inset: 1px;
  background: linear-gradient(135deg, var(--j-gold-50), var(--j-gold-200) 45%, var(--j-gold-500));
  box-shadow: 0 0 calc(var(--gem) * 1.2) rgba(var(--j-gold-rgb), 0.75);
  opacity: 0;
  animation: j-rune-ignite var(--dur) linear infinite;
  animation-delay: inherit;
}

.j-rune > b.is-core { --s: 1.5; }

@keyframes j-rune-fill {
  0% { transform: scaleX(0); opacity: 1; }
  72% { transform: scaleX(1); opacity: 1; }
  92%, 100% { transform: scaleX(1); opacity: 0; }
}

@keyframes j-rune-run {
  0% { transform: translateX(-50%); opacity: 0; }
  5% { opacity: 1; }
  72% { transform: translateX(50%); opacity: 1; }
  80%, 100% { transform: translateX(50%); opacity: 0; }
}

@keyframes j-rune-pulse {
  0%, 26%, 100% { scale: 1; }
  4% { scale: 1.5; }
}

@keyframes j-rune-ignite {
  0%, 100% { opacity: 0; }
  3% { opacity: 1; }
  30% { opacity: 0.4; }
  62% { opacity: 0; }
}

/* Full loader (seasonLoader): the wordmark, the rune line, the caption in tracked gold caps and a rotating line. */
.j-loader {
  display: grid;
  justify-items: center;
  align-content: center;
  min-height: min(62vh, 640px);
  padding: 40px 20px;
  /* The rune line's light runs half its width past each end: keep it from widening a phone page. */
  overflow-x: clip;
  text-align: center;
  animation: j-fade 0.3s ease-out both;
}

/* The header logo's own faces and colours (.j-brand__arena / __sweats), larger, with a light crossing the letters. */
.j-loader__mark {
  --shine-dur: 2.4s;
  display: flex;
  align-items: center;
  font-size: clamp(34px, 4.4vw, 56px);
  line-height: 1.1;
  user-select: none;
}

.j-loader__mark .j-brand__arena {
  font-size: 1em;
  background:
    linear-gradient(100deg, rgba(var(--j-white-rgb), 0) 42%, rgba(var(--j-white-rgb), 0.9) 50%, rgba(var(--j-white-rgb), 0) 58%) 100% 0 / 250% 100% no-repeat,
    linear-gradient(140deg, var(--j-logo-gold-edge), var(--j-logo-gold) 20%, var(--j-logo-gold-light) 50%, var(--j-logo-gold) 80%, var(--j-logo-gold-edge));
  -webkit-background-clip: text;
  background-clip: text;
  animation: j-loader-shine-a var(--shine-dur) linear infinite;
}

.j-loader__mark .j-brand__sweats {
  font-size: 0.8125em;
  margin-left: 0.08em;
  background:
    linear-gradient(100deg, rgba(var(--j-white-rgb), 0) 42%, rgba(var(--j-white-rgb), 0.7) 50%, rgba(var(--j-white-rgb), 0) 58%) 100% 0 / 250% 100% no-repeat,
    linear-gradient(var(--j-logo-red), var(--j-logo-red));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: j-loader-shine-b var(--shine-dur) linear infinite, j-bounce 2.8s ease-in-out infinite;
}

/* The light crosses ARENA over the first 36% of the beat and SWEATS over the next 30%, matching the rule's light. */
@keyframes j-loader-shine-a {
  0% { background-position: 100% 0, 0 0; }
  36%, 100% { background-position: 0 0, 0 0; }
}

@keyframes j-loader-shine-b {
  0%, 34% { background-position: 100% 0, 0 0; }
  66%, 100% { background-position: 0 0, 0 0; }
}

.j-loader .j-rune {
  margin-top: 20px;
}

.j-loader__title {
  margin: 30px 0 0;
  padding-left: var(--j-track-kicker);
  font-family: var(--j-sans);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: var(--j-track-kicker);
  text-transform: uppercase;
  color: var(--j-gold-300);
}

.j-loader__line {
  margin: 12px 0 0;
  min-height: 1.5em;
  font-family: var(--j-sans);
  font-size: 14px;
  color: var(--j-muted);
}

.j-loader__line.is-in {
  animation: j-rise 0.5s var(--j-ease) both;
}

/* Compact loader for tab switches and panels (loading(label)). */
.j-loading {
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 16px;
  min-height: 40vh;
  padding: 40px 20px;
  overflow-x: clip;
  color: var(--j-gold-300);
  font-family: var(--j-sans);
  font-size: 11px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  text-align: center;
}

@media (max-width: 640px) {
  .j-loader { padding: 28px 16px; }
  .j-loader__title { font-size: 11px; letter-spacing: 0.3em; padding-left: 0.3em; }
  .j-loader__line { font-size: 13px; }
}

/* Reduced motion: no light, the rule filled and the diamonds lit (journey.css cuts every animation to one 0.01ms run,
   so these are the resting states). */
@media (prefers-reduced-motion: reduce) {
  .j-rune__fill { opacity: 0.7; }
  .j-rune__glint { display: none; }
  .j-rune > b::after { opacity: 0.55; }
  .j-rune > b.is-core::after { opacity: 1; }
  .j-loader__mark .j-brand__arena,
  .j-loader__mark .j-brand__sweats { background-position: 0 0, 0 0; }
}

/* ---------- States ---------- */

.j-error {
  padding: 24px 28px;
  border: 1px solid rgba(var(--j-red-300-rgb), 0.4);
  border-left: 2px solid var(--j-red-300);
  background: var(--j-panel);
  color: var(--j-text);
}

.j-error .j-kicker {
  color: var(--j-rose);
}

/* Compact failure for one part of a page (retryBox in core.js): a short line and a Retry button. */
.j-retry {
  grid-column: 1 / -1;
  align-self: center;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px 16px;
  padding: 18px 16px;
  border: 1px dashed rgba(var(--j-gold-rgb), 0.22);
  font-size: 11px;
  letter-spacing: var(--j-track-label);
  text-transform: uppercase;
  color: var(--j-muted);
}

.j-retry::before {
  content: "";
  width: 7px;
  height: 7px;
  border: 1px solid var(--j-rose);
  transform: rotate(45deg);
}

.j-retry--page {
  max-width: 520px;
  margin: 12vh auto;
  padding: 28px 20px;
}

.j-empty {
  display: grid;
  place-items: center;
  gap: 10px;
  padding: 40px 20px;
  text-align: center;
  color: var(--j-muted);
}

.j-empty > .j-diamond {
  width: 9px;
  height: 9px;
  background: none;
  border: 1px solid var(--j-gold-300);
}

.j-empty .j-label {
  color: var(--j-dim);
}

.j-skeleton {
  background: linear-gradient(90deg, rgba(var(--j-white-rgb), 0.03), rgba(var(--j-gold-rgb), 0.1), rgba(var(--j-white-rgb), 0.03));
  background-size: 200% 100%;
  animation: j-shimmer 1.4s ease-in-out infinite;
}

/* Locked or unavailable section (access.locked or data not kept for this season). */
.j-locked {
  display: grid;
  place-items: center;
  gap: 8px;
  padding: 30px 16px;
  text-align: center;
  color: var(--j-muted);
}

.j-locked .j-btn {
  margin-top: 6px;
}

/* ---------- Season switch ---------- */

.j-season {
  display: inline-flex;
  border: 1px solid var(--j-line-control);
  background: rgba(var(--j-ink-rgb), 0.6);
}

.j-season__opt {
  padding: 5px 12px;
  font-family: var(--j-sans);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--j-muted);
  transition: color var(--j-dur-fast) var(--j-ease-std), background-color var(--j-dur-fast) var(--j-ease-std);
}

.j-season__opt + .j-season__opt {
  border-left: 1px solid var(--j-line-control);
}

.j-season__opt:hover {
  color: var(--j-gold-100);
  background: rgba(var(--j-gold-rgb), 0.06);
}

.j-season__opt.is-active {
  color: var(--j-gold-50);
  background: rgba(var(--j-gold-rgb), 0.14);
  box-shadow: inset 0 -2px 0 var(--j-gold-300);
}

/* ---------- Motion primitives (README "Motion") ---------- */
/* Entrances fill backwards only (the from-state holds during the delay; nothing lingers after), so hover transitions
   on the same element keep working. Entrances: .j-rise (0.8s, 14px), .j-appear (0.6s, 18px; --from-scale for crests), .j-pop (overshoot from 0.2),
   each delayed by --d. Reveal on scroll: [data-reveal] + revealOnScroll(). Ambient: .j-breathe, .j-breathe-glow,
   .j-bob (nothing turns: the owner wants no spinning rings). Off-screen pause: [data-offscreen]. */

.j-rise { animation: j-rise var(--j-dur-rise) var(--j-ease) backwards; animation-delay: var(--d, 0s); }
.j-appear { animation: j-appear var(--j-dur-appear) var(--j-ease) backwards; animation-delay: var(--d, 0s); }
.j-appear--scale { animation-name: j-appear-scale; }
.j-appear--left { animation-name: j-appear-left; }
.j-pop { animation: j-pop 0.45s var(--j-ease-pop) backwards; animation-delay: var(--d, 0s); }
.j-breathe { animation: j-breathe var(--j-breathe) ease-in-out infinite; animation-delay: var(--d, 0s); }
.j-breathe-glow { animation: j-breathe var(--j-breathe-glow) ease-in-out infinite; animation-delay: var(--d, 0s); }
.j-bob { animation: j-bob 6s ease-in-out infinite; }

[data-reveal] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.5s var(--j-ease-out), transform 0.5s var(--j-ease-out);
  transition-delay: var(--d, 0s);
}

[data-reveal].is-in {
  opacity: 1;
  transform: none;
}

[data-offscreen] *,
[data-offscreen] *::before,
[data-offscreen] *::after {
  animation-play-state: paused !important;
}

@keyframes j-rise {
  from { opacity: 0; transform: translateY(14px); }
}

@keyframes j-appear {
  from { opacity: 0; transform: translateY(18px); }
}

@keyframes j-appear-scale {
  from { opacity: 0; transform: scale(0.8); }
}

@keyframes j-appear-left {
  from { opacity: 0; transform: translateX(-28px); }
}

@keyframes j-reveal {
  from { opacity: 0; transform: translateY(16px); }
}

@keyframes j-pop {
  from { opacity: 0; transform: scale(0.2); }
}

@keyframes j-grow {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

@keyframes j-breathe {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 0.85; }
}

@keyframes j-bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
}

@keyframes j-shimmer {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}

@keyframes j-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* One pass of light across metal: animate a ::after holding var(--j-sheen) (transform only). */
@keyframes j-sheen {
  from { transform: translateX(-110%); }
  to { transform: translateX(110%); }
}

@media (prefers-reduced-motion: reduce) {
  .j-body *,
  .j-body *::before,
  .j-body *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0s !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
  }
  [data-reveal] {
    opacity: 1;
    transform: none;
  }
  .j-btn--as::after {
    display: none;
  }
}

/* ---------- Small screens (the site header's breakpoints live in site/site.css) ---------- */

@media (max-width: 640px) {
  :root { --j-gutter: 12px; }
  .j-head { flex-wrap: wrap; row-gap: 8px; }
  .j-head__meta { flex-wrap: wrap; white-space: normal; gap: 6px 12px; }
  .j-legend { flex-wrap: wrap; gap: 6px 10px; }
  .j-stats > .j-stat { padding: 2px 12px; }
}
