/* ===== Mythic Trials 2 — public site ======================================= */
/* One stylesheet, no build step, no external font or CDN. Dark by design : the
   game is dark fantasy and the site should feel like the same world. */

/* -------------------------------------------------------------------------- */
/* Tokens */

:root {
  --bg:        #0b0912;
  --bg-2:      #100d1c;
  --panel:     #171327;
  --panel-2:   #1e192f;
  --line:      rgba(255, 255, 255, .09);
  --line-soft: rgba(255, 255, 255, .05);

  --text:      #ece8f8;
  --muted:     #9a92b6;
  --dim:       #6f6890;

  --ember:     #ff7a2f;
  --ember-dim: #b2450f;
  --gold:      #f3c356;
  --arcane:    #a97bff;
  --arcane-dim:#5b3fa8;
  --blood:     #d4353f;
  --jade:      #4fd3a0;

  --radius:    14px;
  --radius-sm: 9px;
  /* Wide enough that a full skill bar sits on one row on a 1440-wide screen. */
  --wrap:      1360px;

  --shadow:    0 18px 50px rgba(0, 0, 0, .55);
  --shadow-sm: 0 6px 20px rgba(0, 0, 0, .4);

  --display: Georgia, 'Iowan Old Style', 'Times New Roman', serif;
  --body: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}

/* -------------------------------------------------------------------------- */
/* Reset & base */

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

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.65 var(--body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* A faint arcane glow behind everything, so flat sections never look flat. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(80rem 40rem at 12% -10%, rgba(169, 123, 255, .10), transparent 60%),
    radial-gradient(60rem 34rem at 92% 8%, rgba(255, 122, 47, .08), transparent 60%);
}

img { max-width: 100%; height: auto; display: block; }
a { color: var(--text); text-decoration: none; }
a:hover { color: #fff; }
ul.plain { list-style: none; margin: 0; padding: 0; }
ul.plain li { margin: .35rem 0; }
ul.plain a { color: var(--muted); }
ul.plain a:hover { color: var(--text); }

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 700;
  line-height: 1.12;
  margin: 0 0 .5em;
  letter-spacing: -.01em;
}
h1 { font-size: clamp(2.1rem, 5.2vw, 3.9rem); }
h2 { font-size: clamp(1.6rem, 3.2vw, 2.5rem); }
h3 { font-size: 1.15rem; }

p { margin: 0 0 1rem; }
.muted { color: var(--muted); }
.lede { color: var(--muted); font-size: 1.05rem; max-width: 62ch; }

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 1.25rem; position: relative; z-index: 1; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 99;
  background: var(--ember); color: #180a00; padding: .6rem 1rem; border-radius: 0 0 var(--radius-sm) 0;
}
.skip:focus { left: 0; }

:focus-visible { outline: 2px solid var(--arcane); outline-offset: 3px; border-radius: 4px; }

/* -------------------------------------------------------------------------- */
/* Buttons */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .7rem 1.3rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  font-weight: 700; font-size: .92rem; letter-spacing: .01em;
  cursor: pointer; white-space: nowrap;
  transition: transform .12s ease, background .2s ease, border-color .2s ease, box-shadow .15s ease;
}

/* Deep ember with light text. The earlier bright-orange slab with dark text was
   heavy and low-contrast, and swallowed the store glyph inside it. */
.btn-primary {
  color: #fff4ea;
  background: linear-gradient(180deg, #c8541c 0%, #a53f10 100%);
  border-color: rgba(255, 168, 105, .5);
  text-shadow: 0 1px 1px rgba(60, 20, 0, .55);
  box-shadow:
    inset 0 1px 0 rgba(255, 196, 148, .32),
    0 1px 2px rgba(0, 0, 0, .35);
}
.btn-primary:hover {
  color: #fff;
  background: linear-gradient(180deg, #dc6222 0%, #b84813 100%);
  border-color: rgba(255, 190, 135, .75);
  transform: translateY(-1px);
  box-shadow:
    inset 0 1px 0 rgba(255, 205, 160, .4),
    0 4px 12px rgba(0, 0, 0, .45);
}
.btn-primary:active { transform: translateY(1px); box-shadow: inset 0 2px 4px rgba(60, 20, 0, .45); }

.btn-ghost { background: rgba(255, 255, 255, .04); color: var(--text); }
.btn-ghost:hover { background: rgba(255, 255, 255, .09); border-color: rgba(255, 255, 255, .18); transform: translateY(-1px); }
.btn-sm { padding: .5rem .95rem; font-size: .85rem; border-radius: 8px; }
.btn .ico { width: 17px; height: 17px; fill: currentColor; flex: none; }

/* -------------------------------------------------------------------------- */
/* Top bar */

.topbar {
  position: sticky; top: 0; z-index: 50;
  background: rgba(11, 9, 18, .72);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color .25s ease, background .25s ease;
}
.topbar.is-stuck { border-bottom-color: var(--line); background: rgba(11, 9, 18, .93); }
.topbar-in { display: flex; align-items: center; gap: 1.5rem; min-height: 68px; }

.brand img { width: 130px; height: auto; }

.mainnav { display: flex; align-items: center; gap: 1.35rem; margin-inline-start: auto; }
.mainnav > a {
  color: var(--muted); font-size: .93rem; font-weight: 600;
  padding: .35rem 0; position: relative;
}
.mainnav > a:hover { color: var(--text); }
.mainnav > a.is-active { color: var(--text); }
.mainnav > a.is-active::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -2px; height: 2px;
  background: linear-gradient(90deg, var(--ember), var(--arcane));
  border-radius: 2px;
}

/* `.mainnav > a` is more specific than `.btn-primary`, so it was greying out the
   CTA's label. Restate the colour here, and give it room to breathe. */
.mainnav > a.nav-cta { color: #fff; padding: .5rem 1.5rem; }
.mainnav > a.nav-cta:hover { color: #fff; }
.mainnav > a.nav-cta::after { content: none; }

.navsearch { display: flex; align-items: center; }
.navsearch input {
  width: 9.5rem; background: rgba(255, 255, 255, .05); color: var(--text);
  border: 1px solid var(--line); border-inline-end: 0;
  border-radius: 999px 0 0 999px; padding: .45rem .9rem; font: inherit; font-size: .88rem;
  transition: width .2s ease, background .2s ease;
}
.navsearch input:focus { width: 12.5rem; outline: none; background: rgba(255, 255, 255, .09); }
.navsearch input::placeholder { color: var(--dim); }
.navsearch button {
  background: rgba(255, 255, 255, .05); border: 1px solid var(--line); border-inline-start: 0;
  border-radius: 0 999px 999px 0; padding: .45rem .8rem; cursor: pointer; color: var(--muted);
}
.navsearch button:hover { color: var(--text); background: rgba(255, 255, 255, .1); }
.navsearch svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }

/* Native selects render as a light OS widget with a grey arrow, which looks
   pasted onto a dark page. Strip the chrome and draw our own chevron. */
.langpick select,
.filters select {
  appearance: none; -webkit-appearance: none;
  font: inherit; font-size: .87rem; line-height: 1.2;
  color: var(--text); cursor: pointer;
  padding: .45rem 2rem .45rem .8rem;
  border: 1px solid var(--line); border-radius: 8px;
  background-color: rgba(255, 255, 255, .05);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%239a92b6' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .65rem center;
  background-size: 11px 8px;
  transition: border-color .15s ease, background-color .15s ease;
}
.langpick select:hover,
.filters select:hover { border-color: rgba(255, 255, 255, .22); background-color: rgba(255, 255, 255, .09); }
.langpick select:focus-visible,
.filters select:focus-visible { border-color: var(--arcane); outline: none; }
/* The dropdown list itself is drawn by the OS ; these two properties are the
   only ones it honours, and they keep it from flashing white. */
.langpick select option,
.filters select option { background: #171327; color: var(--text); }
[dir="rtl"] .langpick select,
[dir="rtl"] .filters select { padding: .45rem .8rem .45rem 2rem; background-position: left .65rem center; }

.burger { display: none; background: none; border: 0; padding: .5rem; cursor: pointer; margin-inline-start: auto; }
.burger span { display: block; width: 22px; height: 2px; background: var(--text); border-radius: 2px; margin: 4px 0; transition: transform .2s ease, opacity .2s ease; }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 900px) {
  .burger { display: block; }
  .mainnav {
    position: fixed; inset: 68px 0 auto 0;
    flex-direction: column; align-items: stretch; gap: .25rem;
    background: rgba(13, 11, 22, .98); border-bottom: 1px solid var(--line);
    padding: 1rem 1.25rem 1.5rem;
    transform: translateY(-140%); transition: transform .28s ease;
    max-height: calc(100vh - 68px); overflow-y: auto;
  }
  .mainnav.is-open { transform: translateY(0); }
  .mainnav > a { padding: .7rem 0; border-bottom: 1px solid var(--line-soft); }
  .navsearch { margin-top: .8rem; }
  .navsearch input { width: 100%; }
  .nav-cta { justify-content: center; margin-top: .5rem; }
}

/* -------------------------------------------------------------------------- */
/* Hero */

.hero { position: relative; isolation: isolate; padding: clamp(4rem, 12vh, 8rem) 0 clamp(3rem, 8vh, 6rem); }
.hero-bg {
  position: absolute; inset: 0; z-index: -2; overflow: hidden;
}
/* :not(.hero-logo) — the logo is a sibling inside .hero-bg and must not be
   stretched to cover the section. */
.hero-bg img:not(.hero-logo) { width: 100%; height: 100%; object-fit: cover; object-position: center 38%; }
/* Light enough that the artwork actually reads, dark enough for white text.
   The left column is the only part that needs real contrast. */
.hero-bg::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(to bottom, rgba(11, 9, 18, .18) 0%, rgba(11, 9, 18, .42) 62%, var(--bg) 100%),
    linear-gradient(to right, rgba(11, 9, 18, .78) 0%, rgba(11, 9, 18, .28) 55%, transparent 85%);
}
.hero-in { max-width: 46rem; }
.kicker {
  display: inline-flex; align-items: center; gap: .55rem;
  font-size: .78rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 1.1rem;
}
.kicker::before { content: ''; width: 26px; height: 1px; background: currentColor; }
.hero h1 { margin-bottom: 1rem; text-shadow: 0 2px 6px rgba(0, 0, 0, .85), 0 4px 30px rgba(0, 0, 0, .7); }
.hero .lede { font-size: 1.12rem; color: #cfc8e4; text-shadow: 0 1px 4px rgba(0, 0, 0, .8); }
.hero .kicker, .hero .hero-note { text-shadow: 0 1px 4px rgba(0, 0, 0, .8); }
.hero-actions { display: flex; flex-wrap: wrap; gap: .8rem; margin: 1.4rem 0 1rem; }
.hero-note { font-size: .9rem; color: var(--dim); max-width: 44ch; }

/* The price is the pitch : give it its own line and let it shout. */
.pricetag {
  display: flex; align-items: center; gap: .9rem; flex-wrap: wrap;
  margin: 1.6rem 0 0;
}
.pricetag b {
  font-family: var(--display); font-size: clamp(1.5rem, 3.4vw, 2.2rem); line-height: 1;
  padding: .45rem 1.1rem; border-radius: 12px;
  color: #2a1c00;
  background: linear-gradient(180deg, #ffe08a 0%, #f3c356 45%, #d29a24 100%);
  border: 1px solid rgba(255, 240, 200, .7);
  box-shadow:
    inset 0 1px 0 rgba(255, 250, 230, .7),
    0 2px 0 #8d6413,
    0 8px 20px rgba(0, 0, 0, .5);
  text-shadow: 0 1px 0 rgba(255, 250, 225, .5);
}
.pricetag span { font-size: .92rem; color: var(--muted); max-width: 26ch; text-shadow: 0 1px 4px rgba(0, 0, 0, .8); }

/* The logo sits on the artwork, bottom-left, not in the copy block. */
.hero-logo {
  position: absolute; z-index: 1;
  inset-inline-start: clamp(1.25rem, 4vw, 3rem);
  bottom: clamp(1rem, 4vh, 2.5rem);
  width: clamp(180px, 22vw, 320px); height: auto;
  filter: drop-shadow(0 10px 30px rgba(0, 0, 0, .75));
  pointer-events: none;
}
/* Below the artwork it would collide with the copy — hide it, the top bar
   already carries the wordmark. The artwork itself is pulled back on a phone :
   at that width it sits right behind the text and fights it for attention. */
@media (max-width: 780px) {
  .hero-logo { display: none; }
  .hero-bg img:not(.hero-logo) { opacity: .7; }
}

/* -------------------------------------------------------------------------- */
/* Store buttons */

.stores { display: flex; flex-wrap: wrap; gap: .7rem; }
.store {
  display: inline-flex; align-items: center; gap: .6rem;
  padding: .68rem 1.15rem; border-radius: 999px;
  border: 1px solid var(--line); background: rgba(255, 255, 255, .045);
  font-size: .92rem; font-weight: 600;
  transition: background .2s ease, border-color .2s ease, transform .15s ease;
}
.store:hover { background: rgba(255, 255, 255, .1); border-color: rgba(255, 255, 255, .2); transform: translateY(-1px); }
.store .ico { width: 19px; height: 19px; fill: currentColor; flex: none; }
.store-steam:hover   { border-color: #66c0f4; color: #cfeaff; }
.store-playstore:hover { border-color: var(--jade); color: #cfffed; }
.store-appstore:hover  { border-color: #dcdcdc; color: #fff; }
.stores-foot .store { padding: .55rem .95rem; font-size: .87rem; }

/* -------------------------------------------------------------------------- */
/* Sections */

section { padding: clamp(3rem, 7vw, 5.5rem) 0; position: relative; }
section.tight { padding-block: clamp(2rem, 4vw, 3rem); }

/* The page title block. Its own bottom padding, the lede's margin and the next
   section's top padding all stacked up, leaving the best part of 7rem between a
   heading and the content it introduces. They belong together : the title block
   closes flush, and the section under it opens on a shorter gap. */
/* `section.pagehead`, not `.pagehead` : `section.tight` above out-specifies a bare
   class and kept its own bottom padding. */
section.pagehead { padding-block-end: 0; }
section.pagehead > .wrap > :last-child { margin-bottom: 0; }
section.pagehead + section { padding-block-start: clamp(1.6rem, 3vw, 2.25rem); }
.section-alt { background: linear-gradient(180deg, transparent, var(--bg-2) 12%, var(--bg-2) 88%, transparent); }

.sechead {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 1.5rem;
  margin-bottom: 2rem; flex-wrap: wrap;
}
.sechead h2 { margin-bottom: .35rem; }
.sechead .lede { margin: 0; }

.grid { display: grid; gap: 1.15rem; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fill, minmax(min(17.5rem, 100%), 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fill, minmax(min(13.5rem, 100%), 1fr)); }
/* Wide enough that the four starting skills always fit on a single row. */
.grid-chara { grid-template-columns: repeat(auto-fill, minmax(min(16.5rem, 100%), 1fr)); }

.card {
  background: linear-gradient(160deg, var(--panel), var(--panel-2));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.4rem;
  position: relative; overflow: hidden;
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
a.card:hover, .card.is-link:hover { border-color: rgba(255, 255, 255, .2); transform: translateY(-3px); box-shadow: var(--shadow-sm); }
.card h3 { margin-bottom: .4rem; }
.card p { color: var(--muted); font-size: .95rem; margin: 0; }

/* -------------------------------------------------------------------------- */
/* Stat strip */

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(9.5rem, 100%), 1fr)); gap: 1px;
         background: var(--line); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.stat { background: var(--bg-2); padding: 1.4rem 1.1rem; text-align: center; }
.stat b {
  display: block; font-family: var(--display); font-size: clamp(1.5rem, 3vw, 2.1rem); line-height: 1.1;
  background: linear-gradient(135deg, #fff, var(--gold));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.stat span { display: block; font-size: .78rem; letter-spacing: .09em; text-transform: uppercase; color: var(--dim); margin-top: .35rem; }

/* -------------------------------------------------------------------------- */
/* Mode cards */

/* The artwork gets its own slot at the top of the card. It used to sit behind
   the text as a full-bleed background : the sources are square, so a wide short
   card cropped them to an unreadable strip and every mode looked the same. */
.mode { display: flex; flex-direction: column; padding: 0; overflow: hidden; }
.modeshot {
  width: 100%; aspect-ratio: 16 / 10; object-fit: cover; object-position: center;
  display: block; transition: transform .5s ease;
}
.mode:hover .modeshot { transform: scale(1.05); }
/* The main mode's demon sits high in a square frame — a centred 16:10 crop cuts
   its head off, so pull the window upwards for that one. */
.mode-survivor .modeshot { object-position: center 16%; }

/* Training is the one mode nobody browses a site for : on a phone it is pure
   scrolling cost, so it drops out of the list. */
@media (max-width: 700px) { .mode-training { display: none; } }

/* Store creatives as bands : artwork one side, a line of copy the other. They
   alternate sides down the page so it does not read as a column of slabs. */
.coopband { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 0; padding: 0; overflow: hidden; align-items: stretch; }
.coopband img { width: 100%; height: 100%; object-fit: cover; display: block; }
.coopcopy { padding: 1.6rem 1.8rem; display: flex; flex-direction: column; justify-content: center; }
.coopcopy h2 { font-size: clamp(1.35rem, 2.6vw, 1.9rem); margin-bottom: .5rem; }
.coopcopy .lede { margin: 0; }

/* Flipped : the copy comes first in the grid, the image second. */
.coopband.is-reverse { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); }
.coopband.is-reverse img { grid-column: 2; grid-row: 1; }
.coopband.is-reverse .coopcopy { grid-column: 1; grid-row: 1; }

/* A cut-out creative brings its own torn edge — no frame, no clipping. */
.coopband.is-cutout { border-color: transparent; background: none; box-shadow: none; overflow: visible; }
.coopband.is-cutout img { object-fit: contain; filter: drop-shadow(0 10px 24px rgba(0, 0, 0, .5)); }

@media (max-width: 780px) {
  .coopband, .coopband.is-reverse { grid-template-columns: 1fr; }
  .coopband.is-reverse img { grid-column: 1; grid-row: 1; }
  .coopband.is-reverse .coopcopy { grid-column: 1; grid-row: 2; }
  .coopcopy { padding: 1.2rem 1.3rem 1.4rem; }
}
.modebody {
  display: block; padding: 1.15rem 1.3rem 1.3rem;
  position: relative; margin-top: -2.6rem;
  background: linear-gradient(to bottom, transparent, var(--panel) 2.6rem);
}

.mode .tag {
  align-self: flex-start;
  font-size: .66rem; letter-spacing: .09em; text-transform: uppercase; font-weight: 700;
  color: var(--gold); background: rgba(243, 195, 86, .12);
  border: 1px solid rgba(243, 195, 86, .3);
  padding: .14rem .5rem; border-radius: 999px; margin-bottom: 1rem;
}
.mode h3 { font-size: 1.4rem; margin-bottom: .35rem; }
.mode p { font-size: .93rem; }
.mode .modelink { margin-top: .9rem; font-size: .85rem; font-weight: 600; color: var(--ember); }

/* -------------------------------------------------------------------------- */
/* Showcase screenshots (the store creatives — headline burnt into the image) */

.shots { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr)); }
.shot {
  margin: 0; border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--line); background: var(--panel);
  box-shadow: var(--shadow-sm);
  transition: transform .25s ease, border-color .25s ease, box-shadow .25s ease;
}
.shot img { width: 100%; height: auto; display: block; }
.shot:hover { transform: translateY(-4px); border-color: rgba(255, 255, 255, .2); box-shadow: var(--shadow); }
/* Cut-out creative : let its own torn edges be the edge. */
.shot-cutout { border-color: transparent; background: none; box-shadow: none; overflow: visible; }
.shot-cutout img { filter: drop-shadow(0 12px 26px rgba(0, 0, 0, .55)); }
.shot-cutout:hover { border-color: transparent; box-shadow: none; }
/* Two rows of two, not one hero shot and three small ones. */
@media (min-width: 62rem) { .shots { grid-template-columns: repeat(2, 1fr); } }

/* -------------------------------------------------------------------------- */
/* Characters */

.chara {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: 1.6rem 1.1rem 1.3rem;
}
.chara::before {
  content: ''; position: absolute; inset: -40% 50% auto -10%; height: 70%; z-index: 0;
  background: radial-gradient(circle, rgba(169, 123, 255, .22), transparent 70%);
  filter: blur(20px); opacity: 0; transition: opacity .3s ease;
}
.chara:hover::before { opacity: 1; }
.chara .portrait {
  width: 100%; max-width: 190px; aspect-ratio: 1 / 1; object-fit: contain; object-position: bottom;
  position: relative; z-index: 1;
  filter: drop-shadow(0 12px 22px rgba(0, 0, 0, .55));
  transition: transform .3s ease;
}
.chara:hover .portrait { transform: translateY(-5px) scale(1.03); }
.chara h3 { margin: .9rem 0 .2rem; position: relative; z-index: 1; }
.chara p { font-size: .88rem; position: relative; z-index: 1; }

.affinity {
  display: inline-block; font-size: .72rem; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase;
  padding: .18rem .6rem; border-radius: 999px; margin-bottom: .6rem;
}
.affinity-magic    { color: #c9aaff; background: rgba(169, 123, 255, .14); border: 1px solid rgba(169, 123, 255, .32); }
.affinity-physical { color: #ffb389; background: rgba(255, 122, 47, .13);  border: 1px solid rgba(255, 122, 47, .32); }
.affinity-hybrid   { color: #8fe6c4; background: rgba(79, 211, 160, .12);  border: 1px solid rgba(79, 211, 160, .3); }
.affinity-hardcore { color: #ff9b9f; background: rgba(212, 53, 63, .14);   border: 1px solid rgba(212, 53, 63, .38); margin-inline-start: .3rem; }

.retired { font-size: .78rem; color: var(--dim); margin-top: .5rem; font-style: italic; }

/* Download row under the cross-platform cards */
.crossget {
  display: flex; align-items: center; flex-wrap: wrap; gap: .8rem;
  margin-top: 1.6rem; padding-top: 1.4rem; border-top: 1px solid var(--line);
  font-size: .85rem; letter-spacing: .08em; text-transform: uppercase; font-weight: 700;
}

/* Guardians — the framed portrait cards, grouped by rank */
.rankhead {
  display: flex; align-items: baseline; gap: .8rem; flex-wrap: wrap;
  margin: 2.2rem 0 1rem; font-size: 1.35rem;
}
.rankhead:first-of-type { margin-top: 0; }
.rankhead small {
  font-family: var(--body); font-size: .82rem; font-weight: 400;
  letter-spacing: 0; text-transform: none; color: var(--dim);
}
.rank-guardian  { color: #c9c2e6; }
.rank-elite     { color: var(--arcane); }
.rank-boss      { color: #ff8f5c; }
.rank-lastboss  { color: var(--gold); }
.rank-worldboss { color: var(--blood); }

.cardgrid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(min(13rem, 100%), 1fr)); }
.gcard {
  margin: 0; border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--line); background: var(--panel);
  transition: transform .25s ease, border-color .25s ease, box-shadow .25s ease;
}
.gcard img { width: 100%; height: auto; display: block; }
.gcard:hover { transform: translateY(-4px); border-color: rgba(255, 255, 255, .22); box-shadow: var(--shadow); }
.gcard figcaption { padding: .6rem; text-align: center; font-family: var(--display); }

/* Auras */
.aura-row { display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: center; justify-content: center; }
.aura { display: flex; align-items: center; gap: .8rem; font-size: .92rem; color: var(--muted); }
.aura img { width: 54px; height: 54px; object-fit: contain; }

/* -------------------------------------------------------------------------- */
/* Skills & arcana */

.schoolhead {
  display: flex; align-items: baseline; gap: .8rem;
  margin: 2.5rem 0 1.1rem; padding-bottom: .6rem;
  border-bottom: 1px solid var(--line); font-size: 1.5rem;
}
.schoolhead:first-child { margin-top: 0; }
.schoolhead small { font-size: .78rem; letter-spacing: .1em; text-transform: uppercase;
                    color: var(--dim); font-family: var(--body); font-weight: 700; }
.school-fire     { color: #ff9a5c; }
.school-ice      { color: #7fd8ff; }
.school-electric { color: #ffe066; }
.school-physical { color: #ffb9a3; }
.school-magic    { color: #c9aaff; }
.school-heal     { color: #8fe6c4; }
.school-buff     { color: #e6dcff; }

.skillhead { display: flex; align-items: center; gap: .85rem; margin-bottom: 1rem; }
.skillhead h3 { margin: 0 0 .25rem; }
/* Open card : icon and name up top, types on a full-width row beneath them. */
.skillhead-open {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center;
  column-gap: .85rem; row-gap: .55rem;
}
.skillhead-open h3 { margin: 0; }
.skillhead-open .skilltypes { grid-column: 1 / -1; }
.skillicon {
  width: 56px; height: 56px; flex: none; border-radius: 12px;
  background: rgba(0, 0, 0, .35); border: 1px solid var(--line); padding: 3px;
}
.skilltypes { display: flex; flex-wrap: wrap; gap: .3rem; margin: 0; }
.ttag {
  font-size: .58rem; letter-spacing: .05em; text-transform: uppercase; font-weight: 700;
  color: var(--dim); background: rgba(255, 255, 255, .05);
  border: 1px solid var(--line); border-radius: 999px; padding: .08rem .4rem;
}

.skillsec { border-top: 1px solid var(--line-soft); padding-top: .8rem; margin-top: .8rem; }
.skillsec h4 {
  font-size: .72rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--dim); margin: 0 0 .55rem; font-weight: 700;
}
/* Arcana are the purple tier of progression everywhere else on the site. Closed
   by default, so the summary has to read as something you can open. */
.skillsec-arcana h4 { color: var(--arcane); display: inline; margin: 0; }
.skillsec-arcana > summary {
  cursor: pointer; list-style: none; display: flex; align-items: center; gap: .4rem;
}
.skillsec-arcana > summary::-webkit-details-marker { display: none; }
.skillsec-arcana > summary::before {
  content: "▸"; color: var(--arcane); font-size: .7rem; transition: transform .15s ease;
}
.skillsec-arcana[open] > summary::before { transform: rotate(90deg); }
.skillsec-arcana[open] > summary { margin-bottom: .55rem; }
.skillsec-arcana > summary:focus-visible { outline-offset: 4px; }

.modlist { list-style: none; margin: 0; padding: 0; display: grid; gap: .3rem; }
.modlist li { display: flex; align-items: center; justify-content: space-between; gap: .6rem; font-size: .88rem; }
.modname { cursor: help; border-bottom: 1px dotted var(--line); }
.tierdots { display: inline-flex; gap: 3px; flex: none; }
.dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.dot.tier-1 { background: #5afb50; }
.dot.tier-2 { background: #04aeff; }
.dot.tier-3 { background: #c700dd; }
.dot.off    { background: rgba(255, 255, 255, .1); }

.arclist { list-style: none; margin: 0 0 .7rem; padding: 0; display: grid; gap: .3rem; font-size: .88rem; }
.arclist li { display: flex; justify-content: space-between; gap: .6rem; }
.arclist b { font-weight: 600; color: var(--gold); }
.arclist .muted { font-size: .8rem; white-space: nowrap; }

/* One chip per skill : icon, name, everything else on hover. */
.skillrow { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1.8rem; }
.skillchip {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: .3rem;
  width: 5.4rem; padding: .55rem .3rem;
  font: inherit; color: var(--muted); text-align: center; cursor: pointer;
  border: 1px solid var(--line); border-radius: 10px;
  background: rgba(255, 255, 255, .025);
  transition: border-color .15s ease, background .15s ease, transform .12s ease;
}
.skillchip:hover { border-color: rgba(255, 255, 255, .22); background: rgba(255, 255, 255, .07); transform: translateY(-2px); }
.skillchip img {
  width: 48px; height: 48px; border-radius: 9px; padding: 2px;
  background: rgba(0, 0, 0, .3); border: 1px solid var(--line);
}
.chipname { font-size: .62rem; line-height: 1.15; overflow-wrap: anywhere; }
.skillchip.is-open {
  border-color: rgba(243, 195, 86, .6); background: rgba(243, 195, 86, .1); color: var(--gold);
}

.chiptip {
  position: absolute; z-index: 40; bottom: calc(100% + .5rem); inset-inline-start: 50%;
  transform: translateX(-50%) translateY(4px);
  width: 17rem; padding: .8rem .9rem; text-align: start;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: #14101f; box-shadow: var(--shadow); color: var(--muted);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .15s ease, transform .15s ease, visibility .15s;
}
.skillchip:hover .chiptip, .skillchip:focus-visible .chiptip {
  opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0);
}
.tipstats { display: grid; gap: .1rem; margin: .5rem 0 0; font-size: .78rem; }
.tipstats span { display: flex; justify-content: space-between; gap: .5rem; }
.tipstats b { color: var(--text); font-variant-numeric: tabular-nums; }
.tipopen {
  display: block; margin-top: .5rem; font-size: .7rem; letter-spacing: .07em;
  text-transform: uppercase; font-weight: 700; color: var(--gold);
}

/* Opened skills, side by side, each with its own level. */
.buildgrid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(min(19rem, 100%), 1fr)); }
.buildactions { display: flex; gap: .5rem; }
.buildsaved { font-size: .85rem; color: var(--jade); margin: 0 0 .8rem; overflow-wrap: anywhere; }
.skillcard.is-open { border-color: rgba(243, 195, 86, .35); }
.skillclose {
  margin-inline-start: auto; align-self: flex-start;
  background: none; border: 0; color: var(--dim); cursor: pointer;
  font-size: 1.3rem; line-height: 1; padding: 0 .2rem;
}
.skillclose:hover { color: var(--text); }

.skilllevel {
  display: grid; gap: .3rem; margin: .2rem 0 .9rem;
  padding: .6rem .7rem; border-radius: 8px;
  background: rgba(255, 255, 255, .035); border: 1px solid var(--line-soft);
}
.skilllevel label { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; }
.skilllevel label span {
  font-size: .68rem; letter-spacing: .09em; text-transform: uppercase;
  font-weight: 700; color: var(--dim);
}
.skilllevel output {
  font-family: var(--display); font-size: 1.3rem; color: var(--gold);
  font-variant-numeric: tabular-nums;
}
.skilllevel input[type="range"] { width: 100%; accent-color: var(--ember); }

/* Mod ranges per tier */
.modranges { list-style: none; margin: 0; padding: 0; display: grid; gap: .2rem; font-size: .8rem; }
.modranges li { display: flex; justify-content: space-between; gap: .5rem; color: var(--muted); }
.modranges b { color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* A tier that cannot roll a mod keeps the row, so the three cards read across. */
.modranges li.is-void { min-height: 1.2em; }
.modranges li[title] { cursor: help; }
.modstar { color: var(--gold); font-style: normal; }

/* Per-level stat table on a skill card */
.statlist {
  list-style: none; margin: 0 0 .2rem; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(7.5rem, 100%), 1fr)); gap: .45rem;
}
.statlist li {
  position: relative;
  display: flex; align-items: center; gap: .5rem;
  background: rgba(255, 255, 255, .035); border: 1px solid var(--line-soft);
  border-radius: 8px; padding: .4rem .55rem;
}
/* `display: flex` above would otherwise beat the hidden attribute. */
.statlist li[hidden] { display: none; }
/* The game writes the instance count as `x3` over the damage — same here. */
.instbadge {
  position: absolute; inset-inline-end: .35rem; inset-block-end: .2rem;
  font-family: var(--display); font-style: normal; font-size: .8rem; line-height: 1;
  color: var(--ember); font-variant-numeric: tabular-nums;
}
.tipstats .instbadge { position: static; margin-inline-start: .15rem; font-size: .75rem; }
.staticon { width: 22px; height: 22px; flex: none; object-fit: contain; }
.statname {
  display: block; font-size: .64rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--dim); font-weight: 700;
}
.statval {
  display: block; font-family: var(--display); font-size: 1.05rem; color: var(--text);
  font-variant-numeric: tabular-nums; margin-top: .1rem;
}

/* What the skill does on top of its numbers. Lines the level has not reached are
   hidden outright, so the card always describes the skill as it stands. */
.skilllines {
  list-style: none; margin: .55rem 0 0; padding: 0;
  display: grid; gap: .28rem; font-size: .82rem;
}
.skilllines li { display: flex; align-items: baseline; gap: .45rem; color: var(--text); }
.skilllines li::before { content: "▸"; color: var(--ember); font-size: .7rem; flex: none; }

.tiplines {
  display: grid; gap: .12rem; margin-top: .3rem;
  font-size: .72rem; color: var(--muted);
}
.tiplines i { font-style: normal; color: var(--dim); }

.arclist-detailed { gap: .7rem; }
.arclist-detailed li { display: block; }
.arclist-detailed b { display: inline; }
.arccap {
  font-size: .72rem; font-variant-numeric: tabular-nums; color: var(--dim);
  margin-inline-start: .4rem;
}
.arccap.is-max { color: var(--gold); }
.arcdesc { display: block; color: var(--muted); font-size: .85rem; margin-top: .15rem; }

/* Level picker */
.levelpicker {
  display: flex; align-items: center; flex-wrap: wrap; gap: .8rem;
  padding: .9rem 1.1rem; margin-bottom: 1.8rem;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: linear-gradient(160deg, var(--panel), var(--panel-2));
  position: sticky; top: 76px; z-index: 20;
}
.levelpicker label { font-size: .76rem; letter-spacing: .1em; text-transform: uppercase;
                     font-weight: 700; color: var(--dim); }
.levelpicker input[type="range"] { flex: 1; min-width: 10rem; accent-color: var(--ember); }
.levelpicker output {
  font-family: var(--display); font-size: 1.3rem; color: var(--gold);
  min-width: 1.6rem; text-align: center; font-variant-numeric: tabular-nums;
}
.levelpicker .muted { font-size: .8rem; flex-basis: 100%; }
/* It has to follow on mobile too — that is where you scroll the most. The note
   is dropped there so the bar stays a thin strip rather than a wall. */
@media (max-width: 700px) {
  .levelpicker { top: 8px; padding: .6rem .8rem; gap: .6rem; }
  .levelpicker .muted { display: none; }
}

/* Starting skills : the four always on ONE row, icon over name — like the
   in-game character selector. nowrap, and the cards are sized to fit them. */
.starters {
  display: flex; flex-wrap: nowrap; align-items: flex-start; justify-content: center;
  gap: .45rem; margin: 2.4rem 0 0;
}
.starter {
  display: flex; flex-direction: column; align-items: center; gap: .35rem;
  flex: 1 1 0; min-width: 0;
  font-size: .66rem; line-height: 1.15; text-align: center; color: var(--muted);
  overflow-wrap: anywhere;
}
/* Sized in % so four of them always fit the row, capped at 60px — twice the
   previous size — and never overflowing a narrow card. */
.starter img {
  width: 100%; max-width: 60px; height: auto; aspect-ratio: 1 / 1;
  border-radius: 10px;
  background: rgba(0, 0, 0, .3); border: 1px solid var(--line); padding: 2px;
}

/* The class bonus reads as a gain : green, and set well clear of the skill row
   above it so the two do not read as one block. */
.perktext {
  margin: 1.6rem 0 0; font-size: .8rem; line-height: 1.4;
  color: var(--jade);
}

/* Lore sits last, quieter than the numbers above it. */
.flavor { margin: 1.4rem 0 0; font-size: .85rem; font-style: italic; color: var(--dim); }

/* Player reviews */
.quotes { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr)); }
.quote {
  margin: 0; padding: 1.4rem 1.5rem;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: linear-gradient(160deg, var(--panel), var(--panel-2));
  box-shadow: var(--shadow-sm);
}
.stars { display: flex; gap: 2px; margin-bottom: .7rem; }
.stars svg { width: 15px; height: 15px; fill: var(--gold); }

/* Store rating, top of the hero. A pill rather than plain text : it has to read as
   a badge someone else awarded, not as another line of our own copy. */
.rating {
  /* flex + fit-content, not inline-flex : the kicker above is inline-flex too, and
     the two shared a line. This keeps the pill on its own row without a wrapper. */
  display: flex; width: fit-content; align-items: center; gap: .55rem;
  margin: 0 0 1.1rem; padding: .3rem .8rem .3rem .65rem;
  border: 1px solid rgba(243, 195, 86, .35); border-radius: 999px;
  background: rgba(243, 195, 86, .08);
  font-size: .82rem; color: var(--muted); text-decoration: none;
  backdrop-filter: blur(2px);
}
a.rating:hover { border-color: rgba(243, 195, 86, .6); background: rgba(243, 195, 86, .14); }
.rating b {
  font-family: var(--display); font-size: 1.05rem; color: var(--gold);
  line-height: 1; font-variant-numeric: tabular-nums;
}
/* Two identical star rows stacked, the gold one clipped to the score : 4.8 leaves
   the fifth star 80% full instead of rounding it either way. */
.ratestars { position: relative; display: inline-block; line-height: 0; flex: none; }
.ratestars-bg, .ratestars-on { display: flex; gap: 1px; }
.ratestars-bg svg { fill: rgba(255, 255, 255, .18); }
.ratestars-on {
  position: absolute; inset-block-start: 0; inset-inline-start: 0;
  width: var(--fill); overflow: hidden;
}
.ratestars-on svg { fill: var(--gold); }
.ratestars svg { width: 14px; height: 14px; flex: none; }
.ratetext { white-space: nowrap; }
.ratestore {
  font-size: .68rem; letter-spacing: .07em; text-transform: uppercase; font-weight: 700;
  color: var(--dim); padding-inline-start: .5rem; border-inline-start: 1px solid rgba(243, 195, 86, .28);
}
/* The hero sits on artwork, so the pill needs the same shadow as the text on it. */
.hero .rating { text-shadow: 0 1px 4px rgba(0, 0, 0, .8); }

/* "Mobile" is worth saying on a desktop screen and nowhere else : on a phone the
   reader is already on mobile, and it was the word pushing the pill onto a second
   line. The aria-label keeps the full sentence either way. */
@media (max-width: 700px) {
  .rateplatform { display: none; }
}
/* Tightened rather than wrapped : with "Mobile" gone there is almost enough room
   on a 375px screen, and a second line starting with a divider looks like a
   mistake. Trimming the gaps and a hair of type gets it onto one line. */
@media (max-width: 480px) {
  .rating { gap: .35rem; padding-inline: .55rem .6rem; font-size: .78rem; }
  .rating b { font-size: .98rem; }
  .ratestars svg { width: 12px; height: 12px; }
  .ratestore { font-size: .62rem; padding-inline-start: .4rem; }
}
.quote blockquote {
  margin: 0; font-family: var(--display); font-size: 1.08rem; line-height: 1.55; color: var(--text);
}
.quote figcaption {
  display: flex; align-items: center; gap: .7rem;
  margin-top: 1.1rem; padding-top: .9rem; border-top: 1px solid var(--line-soft);
}
.quote figcaption .avatar {
  width: 40px; height: 40px; border-radius: 50%; flex: none;
  border: 1px solid var(--line); background: rgba(255, 255, 255, .05);
}
.quote figcaption b { display: block; font-size: .95rem; }
.qmeta { display: block; font-size: .78rem; color: var(--dim); }
.quote time { margin-inline-start: auto; font-size: .78rem; color: var(--dim); white-space: nowrap; }

/* Store button inside a cross-platform card */
.storebtn { margin-top: .9rem; }
.crosscard { display: flex; flex-direction: column; align-items: flex-start; }
.crosscard p { flex: 1; }
/* Icon beside the title, not above it. */
.crosstitle { display: flex; align-items: center; gap: .8rem; margin-bottom: .6rem; }
.crosstitle h3 { margin: 0; }
.crosstitle .ico { margin: 0; }
.appicon {
  width: 56px; height: 56px; border-radius: 13px; flex: none;
  border: 1px solid var(--line); box-shadow: var(--shadow-sm);
}

/* Store price, and the sale when one is running. */
.pricebox { display: flex; align-items: baseline; flex-wrap: wrap; gap: .5rem; margin: 0 0 .9rem; flex: 1; }
.pricebox b { font-family: var(--display); font-size: 1.5rem; color: var(--text); }
.pricebox.is-sale b { color: var(--jade); }
.pricecut { color: var(--dim); text-decoration: line-through; font-size: .95rem; }
.pricepct {
  font-size: .74rem; font-weight: 700; letter-spacing: .04em;
  color: #0d2a1f; background: var(--jade); border-radius: 999px; padding: .1rem .5rem;
}
.priceuntil { flex-basis: 100%; font-size: .76rem; color: var(--dim); }
/* Sale with no price to strike through — the percentage carries it. */
.pricebox.is-bare .pricepct-big {
  font-family: var(--display); font-size: 1.5rem; color: #0d2a1f;
  background: var(--jade); border-radius: 10px; padding: .1rem .6rem;
}

.tiercard { text-align: center; }
.tiername { display: block; font-family: var(--display); font-size: 1.05rem; margin-bottom: .5rem; }
.tier-card-1 .tiername { color: #5afb50; }
.tier-card-2 .tiername { color: #04aeff; }
.tier-card-3 .tiername { color: #c700dd; }
.tier-card-4 .tiername { color: #ffff00; }
.tiercard p { font-size: .82rem; }

.iconrow { display: flex; flex-wrap: wrap; gap: .35rem; }
.iconrow img {
  width: 34px; height: 34px; border-radius: 8px;
  background: rgba(0, 0, 0, .3); border: 1px solid var(--line); padding: 2px;
}

.arcanablock { margin-bottom: 1.1rem; }
.arcgrid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr)); }
.arc { border-top: 1px solid var(--line-soft); padding-top: .8rem; }
.arctitle { display: block; color: var(--gold); font-family: var(--display); font-size: 1.05rem; margin-bottom: .35rem; }
.arclevels { font-size: .76rem; letter-spacing: .07em; text-transform: uppercase; margin-bottom: .4rem; }
.arctext { font-size: .9rem; color: var(--muted); margin: 0; }
.lvltable { width: 100%; border-collapse: collapse; font-size: .84rem; }
.lvltable td { padding: .25rem .4rem; border-top: 1px solid var(--line-soft); color: var(--muted); vertical-align: top; }
.lvltable tr:first-child td { border-top: 0; }
.lvltable .lvl {
  width: 1.8rem; text-align: center; color: var(--text); font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* -------------------------------------------------------------------------- */
/* Boards */

.tablewrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel); }
table.board { width: 100%; border-collapse: collapse; min-width: 30rem; }
table.board th {
  text-align: start; font-size: .74rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--dim); font-weight: 700; padding: .85rem 1rem; border-bottom: 1px solid var(--line);
  background: rgba(255, 255, 255, .02); position: sticky; top: 0; backdrop-filter: blur(6px);
}
/* Headers must follow their column's alignment, not the table default —
   otherwise "Best heat & stage" sits left of right-aligned numbers. */
table.board th.c-score, table.board th.c-reward { text-align: end; }
table.board th { white-space: nowrap; }
table.board td { padding: .55rem 1rem; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
table.board tbody tr:last-child td { border-bottom: 0; }
table.board tbody tr { transition: background .15s ease; }
table.board tbody tr:hover { background: rgba(255, 255, 255, .035); }
.c-rank { width: 4.5rem; }
.c-score { text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }
.c-reward { text-align: end; white-space: nowrap; }

.rank {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.1rem; height: 2.1rem; padding: 0 .4rem;
  border-radius: 50px; font-weight: 700; font-size: .9rem;
  background: rgba(255, 255, 255, .05); color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.rank-top { color: var(--text); background: rgba(255, 255, 255, .09); }
.rank-1 { background: linear-gradient(135deg, #f7d774, #c9932b); color: #2a1c00; box-shadow: 0 0 18px rgba(243, 195, 86, .35); }
.rank-2 { background: linear-gradient(135deg, #e6e8ef, #9aa0b0); color: #1c1e25; }
.rank-3 { background: linear-gradient(135deg, #e6a06a, #a4642f); color: #2a1400; }

.pcell { display: flex; align-items: center; gap: .7rem; min-width: 0; }
.pcell .avatar {
  width: 40px; height: 40px; border-radius: 50%; object-fit: cover; flex: none;
  background: rgba(255, 255, 255, .05); border: 1px solid var(--line);
}
.pname { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plevel { color: var(--dim); font-size: .82rem; white-space: nowrap; }
a.pcell:hover .pname { color: var(--gold); }

.pill {
  display: inline-block; font-size: .74rem; font-weight: 700; padding: .15rem .55rem;
  border-radius: 999px; margin-inline-start: .3rem; white-space: nowrap;
}
.pill-gold { color: var(--gold); background: rgba(243, 195, 86, .12); border: 1px solid rgba(243, 195, 86, .28); }
.pill-ring { color: var(--arcane); background: rgba(169, 123, 255, .14); border: 1px solid rgba(169, 123, 255, .3); }

.empty { color: var(--dim); padding: 2rem 0; text-align: center; font-style: italic; }

/* Board tabs */
.tabs { display: flex; flex-wrap: wrap; gap: .45rem; margin-bottom: 1.4rem; }
.tab {
  padding: .48rem 1rem; border-radius: 999px; font-size: .88rem; font-weight: 600;
  border: 1px solid var(--line); background: rgba(255, 255, 255, .035); color: var(--muted);
  transition: all .18s ease;
}
.tab:hover { color: var(--text); background: rgba(255, 255, 255, .08); }
.tab.is-active {
  color: #1c0a00; border-color: transparent;
  background: linear-gradient(135deg, var(--ember), #ff9d3d);
}

.filters { display: flex; flex-wrap: wrap; gap: .8rem; align-items: center; margin-bottom: 1.2rem;
           font-size: .88rem; color: var(--muted); }
.filters select, .filters label { font: inherit; }
.filters label { display: inline-flex; align-items: center; gap: .5rem; cursor: pointer; }

/* Checkbox : the native one is a white OS square on a dark page. */
.filters input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 1.1rem; height: 1.1rem; margin: 0; flex: none; cursor: pointer;
  border: 1px solid var(--line); border-radius: 5px;
  background: rgba(255, 255, 255, .05);
  display: inline-grid; place-content: center;
  transition: background .15s ease, border-color .15s ease;
}
.filters input[type="checkbox"]::before {
  content: ''; width: .55rem; height: .55rem; transform: scale(0);
  background: #2a0f00; transition: transform .12s ease;
  clip-path: polygon(14% 44%, 0 60%, 40% 100%, 100% 22%, 84% 6%, 38% 68%);
}
.filters input[type="checkbox"]:checked {
  background: linear-gradient(180deg, #d9601f, #a53f10); border-color: rgba(255, 168, 105, .6);
}
.filters input[type="checkbox"]:checked::before { transform: scale(1); }
.filters input[type="checkbox"]:hover { border-color: rgba(255, 255, 255, .22); }

.pager { display: flex; gap: .6rem; justify-content: center; align-items: center; margin-top: 1.6rem; }

/* Standings being swapped in : dim, do not collapse — the page must not jump. */
[data-standings] { transition: opacity .12s ease; }
[data-standings].is-loading { opacity: .45; }

/* Preview boards on the homepage. Mythic Trials sits alone on the first row,
   centred and framed in gold — it is the mode the game is named after. */
.boardfeature { display: flex; justify-content: center; margin-bottom: 1.15rem; }
.miniboard.is-featured {
  width: min(30rem, 100%);
  border-color: rgba(243, 195, 86, .45);
  background: linear-gradient(160deg, rgba(243, 195, 86, .07), var(--panel-2));
  box-shadow: 0 0 24px rgba(243, 195, 86, .1);
}
.miniboard.is-featured h3 a { color: var(--gold); }

.miniboard { padding: 1.2rem 1.3rem 1rem; }
.miniboard h3 { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; font-size: 1.05rem; }
.miniboard h3 small { font-size: .72rem; letter-spacing: .08em; text-transform: uppercase; color: var(--dim); font-family: var(--body); font-weight: 700; }
.minirow { display: flex; align-items: center; gap: .65rem; padding: .4rem 0; border-top: 1px solid var(--line-soft); }
.minirow:first-of-type { border-top: 0; }
.minirow .rank { min-width: 1.7rem; height: 1.7rem; font-size: .8rem; }
.minirow .avatar { width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--line); flex: none; }
.minirow .pname { flex: 1; font-size: .92rem; }
.minirow .sc { font-size: .84rem; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* -------------------------------------------------------------------------- */
/* Seasons */

.season-hero { display: grid; gap: 1.5rem; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); align-items: center; }
/* No reward card alongside : one column, or the text sits in half the page with
   nothing next to it. */
.season-hero-solo { grid-template-columns: 1fr; }
@media (max-width: 860px) { .season-hero { grid-template-columns: 1fr; } }

.season-state {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: .74rem; letter-spacing: .12em; text-transform: uppercase; font-weight: 700;
  padding: .25rem .7rem; border-radius: 999px; margin-bottom: .8rem;
}
.state-current  { color: var(--jade);   background: rgba(79, 211, 160, .12);  border: 1px solid rgba(79, 211, 160, .3); }
.state-current::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--jade); box-shadow: 0 0 8px var(--jade); }
.state-upcoming { color: var(--gold);   background: rgba(243, 195, 86, .1);   border: 1px solid rgba(243, 195, 86, .28); }
.state-past     { color: var(--dim);    background: rgba(255, 255, 255, .04); border: 1px solid var(--line); }

/* The next season, when none has run yet : the date is the message. */
.nextseason { text-align: center; padding: 2rem 1.5rem; }
.nextseason h2 { margin: .6rem 0 .8rem; }
.nextseason .lede { margin: 1rem auto 0; }
.nextdate { display: flex; flex-direction: column; align-items: center; gap: .3rem; margin: 0; }
.nextdate b {
  font-family: var(--display); font-size: clamp(1.6rem, 4vw, 2.6rem); line-height: 1;
  background: linear-gradient(135deg, #fff, var(--gold));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.nextdate span { color: var(--muted); font-size: .95rem; }

/* Explainers on the left, reward table alongside. */
.seasonhow { display: grid; gap: 1.15rem; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); align-items: start; }
.seasonhow-points { display: grid; gap: 1.15rem; grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr)); }
.seasonhow-rewards { position: sticky; top: 88px; }
@media (max-width: 900px) {
  .seasonhow { grid-template-columns: 1fr; }
  .seasonhow-rewards { position: static; }
}

.ladderchips { list-style: none; display: flex; flex-wrap: wrap; gap: .35rem; margin: .9rem 0 0; padding: 0; }
.ladderchips li {
  font-size: .76rem; padding: .25rem .6rem; border-radius: 999px;
  border: 1px solid var(--line); background: rgba(255, 255, 255, .04); color: var(--muted);
}
.ladderchips .is-general { color: var(--gold); border-color: rgba(243, 195, 86, .45); }
/* Silver : these two weigh double in the general ranking. */
.ladderchips .is-double {
  color: #dfe3ee; border-color: rgba(223, 227, 238, .5);
  background: rgba(223, 227, 238, .07);
}

.rewards-table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.rewards-table td { padding: .45rem .6rem; border-bottom: 1px solid var(--line-soft); }
.rewards-table td:first-child { color: var(--muted); }
.rewards-table td:last-child { text-align: end; font-variant-numeric: tabular-nums; }

/* -------------------------------------------------------------------------- */
/* Player profile */

/* The left column holds the identity card and the paper doll ; the right one has
   to be wide enough for a full skill bar on one row, so this page runs wider
   than the rest of the site. */
.page-profile .wrap { max-width: 1500px; }
.profile { display: grid; gap: 1.4rem; grid-template-columns: 19rem minmax(0, 1fr); align-items: start; }
.profile > div { display: grid; gap: 1.2rem; align-content: start; }
@media (max-width: 900px) { .profile { grid-template-columns: 1fr; } }

.profile-card { text-align: center; }
.profile-card .portrait { width: 100%; max-width: 230px; margin: 0 auto; filter: drop-shadow(0 14px 26px rgba(0, 0, 0, .55)); }
.profile-card h1 { font-size: clamp(1.6rem, 4vw, 2.2rem); margin: .8rem 0 .2rem; }
.profile-meta { display: grid; gap: .5rem; margin-top: 1.2rem; text-align: start; font-size: .9rem; }
.profile-meta div { display: flex; justify-content: space-between; gap: 1rem; border-top: 1px solid var(--line-soft); padding-top: .5rem; }
.profile-meta dt, .profile-meta span:first-child { color: var(--dim); }

.rankgrid { display: grid; gap: .9rem; grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr)); }
.rankcard { padding: 1rem 1.1rem; display: flex; align-items: center; gap: .9rem; }
/* Rank and "of N" stack in the same column : the total belongs to the rank,
   not to the score next to it. */
.rankcol { display: flex; flex-direction: column; align-items: center; min-width: 3.6rem; flex: none; }
.rankcard .big {
  font-family: var(--display); font-size: 1.7rem; line-height: 1; text-align: center;
  background: linear-gradient(135deg, #fff, var(--gold)); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.rankcard .outof { font-size: .74rem; color: var(--dim); margin-top: .2rem; white-space: nowrap; }
/* Boards the player is not on : shown, but visibly quiet. */
.rankcard.is-unranked { opacity: .5; }
.rankcard .big-none { background: none; color: var(--dim); -webkit-text-fill-color: currentColor; }

/* The character's skill bar, in the game's own slot order. */
.buildblock { margin-top: 2.5rem; }
.buildblock h2 { font-size: 1.3rem; margin-bottom: .8rem; }
.barhead { font-size: 1.2rem; margin-bottom: .8rem; }
.skillbar {
  display: flex; flex-wrap: wrap; gap: .5rem;
  padding: 1rem; border: 1px solid var(--line); border-radius: var(--radius);
  background: linear-gradient(160deg, var(--panel), var(--panel-2));
}
.barslot {
  display: flex; flex-direction: column; align-items: center; gap: .2rem;
  width: 4.6rem; text-align: center;
  padding: .5rem .25rem; border-radius: 10px;
  border: 1px solid transparent; background: rgba(255, 255, 255, .02);
}
.baricon { position: relative; display: block; }
.barslot img, .barslot-blank {
  width: 56px; height: 56px; border-radius: 10px; display: block;
  background: rgba(0, 0, 0, .35); border: 1px solid var(--line); padding: 2px;
}
/* Gear-granted mastery, pinned to the icon it applies to. */
.barplus {
  position: absolute; top: -6px; inset-inline-end: -6px;
  font-size: .68rem; font-weight: 700; line-height: 1;
  color: #fff; background: var(--arcane-dim);
  border: 1px solid var(--arcane); border-radius: 999px; padding: .15rem .3rem;
}
/* The level is the number people scan for : make it the loudest thing here. */
.barlvl {
  font-family: var(--display); font-size: 1.15rem; line-height: 1.1; color: var(--gold);
  font-variant-numeric: tabular-nums;
}
.barslot b { font-size: .6rem; line-height: 1.1; font-weight: 600; color: var(--muted); overflow-wrap: anywhere; }

/* The four bar slots read as the core of the build. */
.barslot.is-main { border-color: rgba(255, 255, 255, .14); background: rgba(255, 255, 255, .055); }

/* The ultimate is the one that decides fights — make it unmistakable. */
.barslot.is-ultimate {
  border-color: rgba(243, 195, 86, .55);
  background: linear-gradient(180deg, rgba(243, 195, 86, .16), rgba(243, 195, 86, .04));
  box-shadow: 0 0 18px rgba(243, 195, 86, .16);
}
.barslot.is-ultimate img { border-color: rgba(243, 195, 86, .5); }
.barslot.is-ultimate b { color: var(--gold); }

.barslot.is-breaker { border-color: rgba(169, 123, 255, .35); background: rgba(169, 123, 255, .07); }

.startertag {
  font-size: .55rem; letter-spacing: .06em; text-transform: uppercase; font-weight: 700;
  color: var(--jade); background: rgba(79, 211, 160, .12);
  border: 1px solid rgba(79, 211, 160, .28); border-radius: 999px;
  padding: .05rem .35rem; margin-top: .1rem;
}

/* Equipped gear : the item's own art, details on hover. */
.setlist { list-style: none; display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 .9rem; padding: 0; }
.setlist li {
  display: inline-flex; align-items: baseline; gap: .4rem; font-size: .8rem;
  padding: .3rem .7rem; border-radius: 999px;
  border: 1px solid var(--line); background: rgba(255, 255, 255, .04); color: var(--muted);
}
.setlist b { color: var(--text); }
.setlist em { font-style: normal; font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; font-weight: 700; }
.setlist .is-earning { border-color: rgba(169, 123, 255, .38); }
.setlist .is-aura { border-color: rgba(79, 211, 160, .4); color: var(--jade); }
.setlist .is-full { border-color: rgba(243, 195, 86, .5); color: var(--gold); }
/* What the set is actually giving, on the pill itself — not only on hover. */
.setgain {
  display: inline-flex; align-items: baseline; gap: .25rem;
  font-size: .74rem; color: var(--jade);
  padding-inline-start: .45rem; margin-inline-start: .1rem;
  border-inline-start: 1px solid var(--line);
}
.setgain i { font-style: normal; color: var(--dim); font-size: .68rem; }

/* Paper doll : armour down the left, weapon / gloves / rings down the right.
   The pills sit outside their cell, so the gaps have to clear them — "8
   overloads" is much wider than the "+8" it replaced. */
.gearcard h3 { margin-bottom: .9rem; }
.gearcols { display: grid; grid-template-columns: 1fr 1fr; column-gap: 1.8rem; row-gap: 1.4rem; }
.gearcol { display: grid; gap: 1.4rem; justify-items: center; }
.gearcell.is-empty {
  border-style: dashed; border-color: var(--line-soft); background: rgba(255, 255, 255, .015);
  cursor: default;
}
.gearcell.is-empty .gearcell-blank { opacity: .25; }
.gearcell {
  position: relative; width: 72px; height: 72px; flex: none;
  border-radius: 10px; border: 1px solid var(--line);
  background: rgba(0, 0, 0, .3);
  display: grid; place-items: center; cursor: help;
}
.gearcell img, .gearcell-blank { width: 64px; height: 64px; object-fit: contain; }
/* A set piece gets a thicker, double-lined frame — a unique can be one too, and
   then it carries both marks. */
.gearcell.in-set {
  border-width: 2px; border-color: rgba(79, 211, 160, .6);
  box-shadow: inset 0 0 0 1px rgba(79, 211, 160, .22), 0 0 10px rgba(79, 211, 160, .12);
}
.gearcell.gear-unique {
  border-color: rgba(243, 195, 86, .6);
  box-shadow: inset 0 0 12px rgba(243, 195, 86, .14);
}
.gearcell.gear-unique.in-set {
  border-width: 2px; border-color: rgba(243, 195, 86, .75);
  box-shadow: inset 0 0 0 1px rgba(79, 211, 160, .45), 0 0 12px rgba(243, 195, 86, .18);
}
.gearover, .gearplus {
  position: absolute; font-size: .62rem; font-weight: 700; line-height: 1;
  border-radius: 999px; padding: .14rem .36rem; white-space: nowrap;
}
.gearover { bottom: -7px; inset-inline-end: -7px; color: #2a1c00; background: var(--gold); }
.gearplus { top: -7px; inset-inline-end: -7px; color: #fff; background: var(--arcane-dim); border: 1px solid var(--arcane); }

/* Tooltip. Shown on hover and on keyboard focus — the cell is focusable. */
.geartip {
  position: absolute; z-index: 60; bottom: calc(100% + .5rem); inset-inline-start: 50%;
  transform: translateX(-50%) translateY(4px);
  width: 15rem; max-width: calc(100vw - 1.5rem); padding: .8rem .9rem; text-align: start;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: #14101f; box-shadow: var(--shadow);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .15s ease, transform .15s ease, visibility .15s;
}
.gearcell:hover .geartip, .gearcell:focus-visible .geartip {
  opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0);
}
[dir="rtl"] .geartip { transform: translateX(50%) translateY(4px); }
[dir="rtl"] .gearcell:hover .geartip { transform: translateX(50%) translateY(0); }

/* A 15rem tooltip centred on a 72px cell hangs ~5rem past it on each side, which
   pushed it out of the card on the outer columns. Anchor it to the column's inner
   edge instead of centring it, and it always lands inside. */
.gearcols > .gearcol:first-child .geartip,
.gearcols > .gearcol:first-child .gearcell:hover .geartip {
  inset-inline-start: 0; transform: none;
}
.gearcols > .gearcol:last-child .geartip,
.gearcols > .gearcol:last-child .gearcell:hover .geartip {
  inset-inline-start: auto; inset-inline-end: 0; transform: none;
}
.gearcols > .gearcol:first-child .geartip,
.gearcols > .gearcol:last-child .geartip { transform: translateY(4px); }
.gearcols > .gearcol:first-child .gearcell:hover .geartip,
.gearcols > .gearcol:first-child .gearcell:focus-visible .geartip,
.gearcols > .gearcol:last-child .gearcell:hover .geartip,
.gearcols > .gearcol:last-child .gearcell:focus-visible .geartip { transform: translateY(0); }
.tipname { display: block; font-family: var(--display); font-size: 1rem; }
.tipslot { font-size: .62rem; letter-spacing: .09em; text-transform: uppercase; color: var(--dim); }
.tipmeta { display: block; font-size: .74rem; color: var(--dim); margin-top: .15rem; }
/* Overloads read in the same gold as their pill, so the two connect. */
.tipmeta.is-overload { color: var(--gold); }

/* Set chips carry their own tooltip listing every tier and what is reached. */
.setlist li { position: relative; cursor: help; }
/* Downward, not upward : the set pills sit at the very top of the gear card, so
   opening above put the panel outside the card, where it was clipped and covered
   by whatever followed. There is always room below. */
.settip {
  position: absolute; z-index: 60; top: calc(100% + .5rem); inset-inline-start: 0;
  width: 17rem; max-width: calc(100vw - 1.5rem); padding: .8rem .9rem; text-align: start;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: #14101f; box-shadow: var(--shadow); color: var(--muted);
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateY(4px);
  transition: opacity .15s ease, transform .15s ease, visibility .15s;
}
.setlist li:hover .settip, .setlist li:focus-visible .settip {
  opacity: 1; visibility: visible; transform: translateY(0);
}
/* A tap does not raise :focus-visible, so on touch the panel never opened. */
.setlist li:focus .settip { opacity: 1; visibility: visible; transform: translateY(0); }
.gearcell:focus .geartip { opacity: 1; visibility: visible; }
.setbonuses { list-style: none; margin: .5rem 0 0; padding: 0; display: grid; gap: .3rem; }
.setbonuses li { display: flex; gap: .5rem; font-size: .78rem; opacity: .45; }
.setbonuses li.is-on { opacity: 1; color: var(--text); }
.setbonuses li b {
  flex: none; width: 1.3rem; height: 1.3rem; border-radius: 50%;
  display: grid; place-items: center; font-size: .68rem;
  background: rgba(255, 255, 255, .07); color: var(--muted);
}
.setbonuses li.is-on b { background: var(--jade); color: #0d2a1f; }
.gearkind { font-size: .64rem; letter-spacing: .07em; text-transform: uppercase; font-weight: 700; }
.gearkind.is-unique { color: var(--gold); }
.gearkind.is-set { color: var(--jade); }
.gearstats { list-style: none; margin: .5rem 0 0; padding: 0; display: grid; gap: .15rem; font-size: .78rem; }
.gearstats li { display: flex; justify-content: space-between; gap: .5rem; color: var(--muted); }
.gearstats b { color: var(--text); font-variant-numeric: tabular-nums; }
.gearskills {
  margin: .5rem 0 0; font-size: .78rem; color: var(--arcane);
  border-top: 1px solid var(--line-soft); padding-top: .45rem;
}
.gearability { margin: .35rem 0 0; font-size: .78rem; color: var(--gold); }

/* On a phone there is no room to float a 17rem panel next to anything : anchored
   to a pill it opened past the card and got covered, anchored to a gear cell it
   ran off the side. Both become a sheet pinned to the bottom of the viewport, so
   they sit over everything, always fit, and are dismissed by tapping elsewhere. */
@media (max-width: 620px) {
  .settip, .geartip {
    position: fixed; z-index: 200;
    inset-inline: .75rem; inset-block-end: .75rem; inset-block-start: auto;
    width: auto; max-width: none; max-height: 70vh; overflow-y: auto;
    transform: translateY(8px);
    box-shadow: 0 -6px 30px rgba(0, 0, 0, .55), var(--shadow);
  }
  .setlist li:hover .settip, .setlist li:focus .settip,
  .setlist li:focus-visible .settip,
  .gearcell:hover .geartip, .gearcell:focus .geartip,
  .gearcell:focus-visible .geartip,
  .gearcols > .gearcol:first-child .gearcell:hover .geartip,
  .gearcols > .gearcol:first-child .gearcell:focus-visible .geartip,
  .gearcols > .gearcol:last-child .gearcell:hover .geartip,
  .gearcols > .gearcol:last-child .gearcell:focus-visible .geartip {
    transform: translateY(0);
  }
  /* The per-column anchoring above is meaningless once the sheet is viewport-wide. */
  .gearcols > .gearcol:first-child .geartip,
  .gearcols > .gearcol:last-child .geartip {
    inset-inline: .75rem; transform: translateY(8px);
  }
  /* Full-width pills, so a long bonus line has somewhere to go. */
  .setlist { flex-direction: column; align-items: stretch; }
  .setlist li { border-radius: var(--radius-sm); flex-wrap: wrap; }
}

/* Placeholder rows while an async panel is on its way. */
.skel {
  height: 2.6rem; border-radius: var(--radius-sm); margin-bottom: .5rem;
  background: linear-gradient(90deg, rgba(255, 255, 255, .04) 25%,
              rgba(255, 255, 255, .09) 37%, rgba(255, 255, 255, .04) 63%);
  background-size: 400% 100%;
  animation: skel 1.3s ease infinite;
}
@keyframes skel { from { background-position: 100% 50%; } to { background-position: 0 50%; } }
@media (prefers-reduced-motion: reduce) { .skel { animation: none; } }
.profile-meta .skel { height: 1.6rem; }
[data-player-part].is-in { animation: fadein .25s ease; }
@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }
.rankcard .lbl { font-size: .82rem; color: var(--dim); letter-spacing: .06em; text-transform: uppercase; font-weight: 700; }
.rankcard .val { font-size: .95rem; }

.medals { display: flex; flex-wrap: wrap; gap: .5rem; }
.medal {
  display: inline-flex; align-items: center; gap: .45rem; font-size: .84rem;
  padding: .35rem .75rem; border-radius: 999px; border: 1px solid var(--line);
  background: rgba(255, 255, 255, .04);
}
.medal b { font-weight: 700; }
.medal-1 { border-color: rgba(243, 195, 86, .5); color: var(--gold); }
.medal-2 { border-color: rgba(230, 232, 239, .35); }
.medal-3 { border-color: rgba(230, 160, 106, .4); }

/* Search */
.searchbox { display: flex; gap: .6rem; max-width: 32rem; margin-bottom: 2rem; }
.searchbox input {
  flex: 1; background: rgba(255, 255, 255, .05); border: 1px solid var(--line); color: var(--text);
  border-radius: 999px; padding: .8rem 1.2rem; font: inherit;
}
.searchbox input:focus { outline: none; border-color: var(--arcane); background: rgba(255, 255, 255, .08); }

.resultlist { display: grid; gap: .5rem; }
.result {
  display: flex; align-items: center; gap: .9rem; padding: .7rem 1rem;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel);
  transition: border-color .18s ease, background .18s ease, transform .18s ease;
}
.result:hover { border-color: rgba(255, 255, 255, .2); background: var(--panel-2); transform: translateX(3px); }
.result .avatar { width: 42px; height: 42px; border-radius: 50%; border: 1px solid var(--line); flex: none; }
.result .who { flex: 1; min-width: 0; }
.result .who b { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.result .who span { font-size: .84rem; color: var(--dim); }

/* -------------------------------------------------------------------------- */
/* Cross-platform band */

.cross { display: grid; gap: 1.2rem; grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr)); margin-top: 2rem; }
.crosscard { padding: 1.3rem; }
.crosscard .ico {
  width: 34px; height: 34px; fill: none; stroke: var(--ember); stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round; margin-bottom: .7rem;
}

/* -------------------------------------------------------------------------- */
/* Footer */

.footer { border-top: 1px solid var(--line); background: var(--bg-2); padding: 3rem 0 1.5rem; margin-top: 2rem; position: relative; z-index: 1; }
.footer-in { display: grid; gap: 2rem; grid-template-columns: 1.4fr repeat(3, 1fr); }
@media (max-width: 860px) { .footer-in { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .footer-in { grid-template-columns: 1fr; } }
.footcol h3 { font-family: var(--body); font-size: .78rem; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); margin-bottom: .8rem; }
.footcol-brand img { width: 150px; margin-bottom: .8rem; }
.footcol-brand p { font-size: .9rem; max-width: 22rem; }
.footer-legal {
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: .5rem;
  border-top: 1px solid var(--line); margin-top: 2.5rem; padding-top: 1.2rem;
  font-size: .82rem; color: var(--dim);
}

/* -------------------------------------------------------------------------- */
/* Legal pages */

.legal { max-width: 46rem; }
.legal h1 { margin-bottom: 1.5rem; }
.legal h2 { font-size: 1.3rem; margin: 2.2rem 0 .7rem; color: var(--gold); }
.legal p, .legal li { color: var(--muted); line-height: 1.75; }
.legal ol { padding-inline-start: 1.4rem; margin: 0 0 1rem; }
.legal li { margin-bottom: .6rem; }
.legal a { color: var(--arcane); text-decoration: underline; text-underline-offset: 2px; }
.legal a:hover { color: #c9aaff; }

.legallinks { display: flex; gap: 1rem; flex-wrap: wrap; }
.legallinks a { color: var(--dim); }
.legallinks a:hover { color: var(--text); }

/* -------------------------------------------------------------------------- */
/* News
   Each release is a <details> : folded it is a one-line summary with the version
   and the date ; opened, the full patch notes. */

.newsfilters { margin-bottom: 1.6rem; }

.newsfeed { display: grid; gap: .9rem; max-width: 52rem; }
.newsitem { padding: 0; overflow: hidden; }

.newsitem > summary {
  cursor: pointer; list-style: none; padding: 1rem 1.15rem;
  display: grid; grid-template-columns: auto 1fr; align-items: center;
  column-gap: .9rem; row-gap: .45rem;
  transition: background .15s ease;
}
.newsitem > summary::-webkit-details-marker { display: none; }
.newsitem > summary:hover { background: rgba(255, 255, 255, .03); }
.newsitem[open] > summary { border-bottom: 1px solid var(--line-soft); }

/* The version is the headline : it is what a reader scans the feed for. */
.newsver {
  font-family: var(--display); font-size: 1.05rem; color: var(--gold);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.newsver::after {
  content: "▸"; color: var(--dim); font-size: .68rem; margin-inline-start: .5rem;
  display: inline-block; transition: transform .15s ease;
}
.newsitem[open] .newsver::after { transform: rotate(90deg); }

.newsmeta {
  display: flex; align-items: center; gap: .55rem; flex-wrap: wrap;
  font-size: .76rem; color: var(--dim);
}
.newscount {
  border: 1px solid var(--line); border-radius: 999px; padding: .05rem .45rem;
  letter-spacing: .04em;
}
/* Today's or yesterday's release : loud on purpose, it is the one thing a returning
   player looks for in the feed. */
.newsnew {
  border-radius: 999px; padding: .05rem .5rem;
  background: var(--jade); color: #04120a;
  font-weight: 700; font-size: .7rem; letter-spacing: .08em;
  box-shadow: 0 0 12px rgba(79, 211, 160, .35);
}

/* The summary line spans the whole row underneath the version and the date. */
.newssum {
  grid-column: 1 / -1; color: var(--muted); font-size: .9rem; line-height: 1.5;
}
.newsitem[open] .newssum { color: var(--dim); }

.newsbody { padding: 1.1rem 1.15rem 1.3rem; }
.newsbody p { color: var(--muted); line-height: 1.7; margin: 0 0 .8rem; }
.newsbody .newsh {
  font-size: 1rem; margin: 1.5rem 0 .7rem; color: var(--text);
  letter-spacing: .02em;
}
.newsbody > .newsh:first-child { margin-top: 0; }
.newslist { list-style: none; margin: 0 0 1rem; padding: 0; display: grid; gap: .5rem; }
/* Deliberately NOT flex. A bullet line holds <strong> and <span> runs, and each of
   those becomes its own flex item sized to max-content — the row then grows past
   the card instead of wrapping, and `overflow: hidden` swallowed the rest. Block
   layout with an absolutely placed marker wraps like prose. */
.newslist li {
  position: relative; padding-inline-start: 1.1rem;
  color: var(--muted); line-height: 1.6; font-size: .92rem;
}
.newslist li::before {
  content: "▪"; color: var(--ember); position: absolute;
  inset-inline-start: 0; top: 0; line-height: 1.6;
}
/* A line that names a skill leads with that skill's own icon.
   `display: inline-block` is mandatory : the global `img { display: block }` reset
   would otherwise push the text of the line under the icon. */
.newsskill {
  display: inline-block;
  width: 24px; height: 24px; border-radius: 6px;
  background: rgba(0, 0, 0, .3); border: 1px solid var(--line); padding: 1px;
  vertical-align: -.35rem; margin-inline-end: .4rem;
}

.newsfallback {
  font-size: .8rem; color: var(--dim); font-style: italic;
  border-inline-start: 2px solid var(--line); padding-inline-start: .7rem;
  margin: 0 0 1rem;
}

@media (max-width: 620px) {
  .newsitem > summary { grid-template-columns: 1fr; }
}

/* -------------------------------------------------------------------------- */
/* Mobile store bar
   Pinned to the bottom of a phone screen once the hero's buttons have scrolled
   away, so "buy it" is never more than a thumb away. Hidden on wider screens,
   where the header CTA is always visible anyway. */

.storebar { display: none; }

@media (max-width: 760px) {
  .storebar {
    display: grid; grid-template-columns: repeat(3, 1fr);
    position: fixed; inset-inline: 0; inset-block-end: 0; z-index: 90;
    background: rgba(13, 11, 22, .92);
    border-block-start: 1px solid var(--line);
    box-shadow: 0 -8px 24px rgba(0, 0, 0, .45);
    padding: .35rem .35rem calc(.35rem + env(safe-area-inset-bottom));
    gap: .3rem;
    /* Out of the way until site.js says otherwise, and never animated for a
       visitor who asked for stillness. */
    transform: translateY(110%);
    transition: transform .25s ease;
  }
  .storebar.is-in { transform: none; }

  .storebar-link {
    display: flex; flex-direction: column; align-items: center; gap: .18rem;
    padding: .4rem .2rem; border-radius: var(--radius-sm);
    color: var(--muted); text-decoration: none;
    font-size: .62rem; letter-spacing: .04em; text-transform: uppercase; font-weight: 700;
    text-align: center; line-height: 1.1;
  }
  .storebar-link .ico { width: 20px; height: 20px; fill: currentColor; }
  .storebar-link:active { background: rgba(255, 255, 255, .06); }
  /* Google Play is the one with the rating behind it, so it leads in gold. */
  .storebar-playstore { color: var(--gold); }

  /* The bar floats over the page, so the footer needs room to clear it. */
  body.page-home .footer { padding-bottom: 4.5rem; }
}

@media (prefers-reduced-motion: reduce) {
  .storebar { transition: none; }
}

/* -------------------------------------------------------------------------- */
/* Lazy blocks
   A block whose content costs real queries reserves its height with skeletons, so
   the page does not jump when the answer lands. The heights are deliberately close
   to what actually arrives. */

.lazyblock { display: grid; gap: .9rem; }
.lazy-stats .skel   { height: 6.5rem; }
.lazy-boards .skel  { height: 11rem; }
.lazy-boards .skel:first-child { height: 13rem; }
.lazy-season .skel  { height: 8rem; }
.lazyblock.is-in { display: block; gap: 0; }
.lazyblock.is-failed { display: none; }
/* The skeletons never animate for a visitor who asked for stillness. */
@media (prefers-reduced-motion: reduce) {
  .skel { animation: none; }
}

/* -------------------------------------------------------------------------- */
/* Utilities */

.center { text-align: center; }
.mt-2 { margin-top: 2rem; }
.hr { height: 1px; background: var(--line); border: 0; margin: 2.5rem 0; }
.badge-live {
  display: inline-flex; align-items: center; gap: .4rem; font-size: .76rem; color: var(--dim);
}
.badge-live::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--jade); box-shadow: 0 0 7px var(--jade); }

.reveal { opacity: 0; transform: translateY(18px); transition: opacity .6s ease, transform .6s ease; }
.reveal.is-in { opacity: 1; transform: none; }
