/* ==========================================================================
   creator.playprimetanki.com: the whole design system, one file.

   Order of this file:
     1  fonts                 9  skip link           17  leaderboard
     2  tokens               10  hero                18  FAQ
     3  base and reset       11  counters            19  buttons
     4  type                 12  plates              20  footer
     5  page sky             13  tier cards          21  responsive
     6  header               14  reward blocks       22  lite mode
     7  phone menu sheet     15  the step route      23  reduced motion
     8  language switcher    16  the form            24  display font per language

   House rules this file keeps: only transform and opacity animate, no filter or
   backdrop-filter on anything bigger than the header bar, no !important, no
   inline styles, every page centred by .c-shell, 3px focus rings on everything
   interactive, phone inputs at 48px and 16px, nothing wider than the screen at
   320px.

   Shared art and fonts arrive at this site's root at deploy time, so every path
   here is absolute (/assets/...).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Fonts. Copied from the main site's styles.css so the two sites are set in
   the same metal. Anton is the sub-brand's display voice; Inter is everything
   else; Tanki Quadrat is the FIGHT! button's own lettering (the label is text,
   so it reads in every language). Prime Intl carries the scripts the Latin
   files lack, each scoped by unicode-range, so Latin never falls through to it.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Prime Display";
  src: url("/assets/fonts/anton-v27-latin-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Prime Text";
  src: url("/assets/fonts/inter-v20-latin-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Tanki Quadrat";
  src: url("/assets/fonts/quadrat-game.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Prime Intl";
  src: url("/assets/fonts/noto-sans-georgian-v48-georgian-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0589, U+10A0-10FF, U+1C90-1CBF, U+2D00-2D2F;
}

/* Cyrillic is Inter's own cut, the same version as the Latin file above, so
   Russian reads as the site's typeface and not a lookalike. */
@font-face {
  font-family: "Prime Intl";
  src: url("/assets/fonts/inter-v20-cyrillic-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

/* Armenian is declared after Georgian on purpose: both claim U+0589, the
   Armenian full stop, and where two ranges overlap the last one wins. */
@font-face {
  font-family: "Prime Intl";
  src: url("/assets/fonts/noto-sans-armenian-v47-armenian-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0530-058F, U+FB13-FB17;
}

/* --------------------------------------------------------------------------
   2. Tokens. Ground and edges are the main site's, so the two sites sit on the
   same night. The metals are the game's own: gold sampled from the Gold Box and
   the game's first-place numeral, silver and bronze from the ratings site the
   owner already reviewed. Nothing here is invented colour.
   -------------------------------------------------------------------------- */
:root {
  color-scheme: dark;

  /* Ground: cool metal greys, continuous with the main site's --page */
  --c-void: #05080c;
  --c-plate: #0e141b;
  --c-plate-up: #141c25;
  --c-plate-hi: #1c2631;
  --c-field: rgba(4, 9, 15, 0.8);
  --c-edge: rgba(173, 196, 215, 0.18);
  --c-edge-strong: rgba(190, 210, 226, 0.35);
  --c-edge-lit: rgba(255, 255, 255, 0.06);
  --c-edge-dark: rgba(0, 0, 0, 0.55);

  /* Text */
  --c-text: #f1f4f6;
  --c-body: #c3cfd8;
  --c-muted: #9aa9b5;
  --c-fine: #7f8f9b;

  /* Dust: the real tone of the game's maps. -deep is grading only, never text. */
  --c-dust: #b3a280;
  --c-dust-deep: #6e614b;

  /* Crystal gold: the Gold Box and first place */
  --c-gold-hi: #faeaa5;
  --c-gold: #f6d556;
  --c-gold-mid: #d4a63f;
  --c-gold-deep: #8a6a20;

  /* Silver and bronze: the ratings site's stops */
  --c-silver-hi: #eef4fa;
  --c-silver: #b9c6d4;
  --c-silver-deep: #77899b;
  --c-bronze-hi: #e8bd97;
  --c-bronze: #c9925e;
  --c-bronze-deep: #7d5433;

  /* Game UI blue */
  --c-crystal: #208ec4;
  --c-crystal-hi: #63aac2;
  --c-crystal-deep: #225b88;
  --c-hud: #4090f0;
  --c-moon: #85bfe5;

  /* Brand */
  --c-orange: #f59a32;
  --c-orange-hi: #ffc063;
  --c-orange-deep: #6c3511;
  --c-orange-glow: rgba(243, 120, 20, 0.28);

  /* Discord, unchanged from the main site */
  --c-discord: #5865f2;
  --c-discord-deep: #4752c4;
  --c-discord-press: #3c45a5;
  --c-discord-light: #8c95ff;

  /* Status */
  --c-up: #6fdc9a;
  --c-down: #ff8f7a;
  --c-warn: #ffd39a;
  --c-urgent: #ff6b5a;

  /* Radii. Plates stay at 6px: over-rounded cards read as a template. */
  --r-plate: 6px;
  --r-control: 12px;
  --r-inner: 8px;
  --r-round: 50%;

  /* Shadows. The lift shadow rides a pseudo-element's opacity, never box-shadow. */
  --sh-plate:
    inset 0 1px 0 var(--c-edge-lit),
    inset 0 -1px 0 var(--c-edge-dark),
    inset 0 0 0 1px var(--c-edge),
    0 24px 55px rgba(0, 0, 0, 0.34);
  --sh-lift: 0 20px 42px rgba(0, 0, 0, 0.42);
  --sh-art: 0 35px 66px rgba(0, 0, 0, 0.55);
  --glow-gold: 0 0 40px -10px rgba(212, 166, 63, 0.35);
  --glow-orange: 0 0 22px var(--c-orange-glow), 0 12px 26px rgba(0, 0, 0, 0.4);

  /* Space, 4px base */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;
  --s-8: 72px;
  --s-9: 112px;
  --section-y: clamp(72px, 9vw, 128px);

  /* The one container. Every page is centred by it. */
  --gutter: 24px;
  --shell: min(1180px, calc(100% - 48px));

  /* Chrome */
  --header-h: 80px;

  /* Motion */
  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-snap: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-expo: cubic-bezier(0.22, 1, 0.36, 1);
  --t-fast: 150ms;
  --t-base: 190ms;
  --t-slow: 420ms;

  /* How long one item of the activity strip takes to cross. The lap is worked
     out from it in section 17, so the strip runs at one speed whatever it is
     carrying. */
  --ticker-step: 3s;
}

/* --------------------------------------------------------------------------
   3. Base and reset.
   -------------------------------------------------------------------------- */
* {
  box-sizing: border-box;
}
 would beat it and the strip would show
   while the page still says it is hidden. Naming the attribute twice outweighs
   a single class whatever the order, so no component has to repeat the rule and
   a new one cannot forget it. */
[hidden][hidden] {
  display: none;
}

html {
  min-width: 320px;
  overflow-x: clip;
  /* the pinned bar would cover the top of whatever an anchor jumps to */
  scroll-padding-top: calc(var(--header-h) + 8px);
  scroll-behavior: smooth;
  scrollbar-color: #263747 var(--c-void);
}

.c-body {
  position: relative;
  min-height: 100vh;
  margin: 0;
  overflow-x: clip;
  background: var(--c-void);
  color: var(--c-body);
  font-family: "Prime Text", "Prime Intl", Arial, sans-serif;
  font-size: 1.125rem;
  line-height: 1.65;
}

/* The page locks while the menu sheet is open (creator-site.js toggles it). */
.c-body.nav-open {
  overflow: hidden;
}

.c-body > * {
  position: relative;
  z-index: 1;
}

/* The footer's fade starts above the last section and belongs behind the page. */
main {
  position: relative;
  z-index: 2;
  isolation: isolate;
}

h1,
h2,
h3,
h4,
p,
ul,
ol,
figure,
blockquote,
dl,
dd {
  margin: 0;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
  text-decoration: none;
}

img,
video {
  display: block;
  max-width: 100%;
}

button,
a {
  -webkit-tap-highlight-color: transparent;
}

button {
  color: inherit;
  font: inherit;
}

input,
select,
textarea {
  font: inherit;
}

/* One visible focus ring, everywhere. */
:focus-visible {
  outline: 3px solid var(--c-orange-hi);
  outline-offset: 3px;
}

/* The only container on the site. Content goes in it, and the page is centred. */
.c-shell {
  width: var(--shell);
  margin-inline: auto;
}

.c-section {
  padding-block: var(--section-y);
}

/* One gap between two sections, not two: the lower one keeps the rhythm and the
   upper one stops paying for it twice. */
.c-section + .c-section {
  padding-top: 0;
}

/* On a desktop screen the bar is fixed, so a page that opens with a section
   instead of the hero has to start below it. Below 981 the bar is sticky and
   takes its own room, so nothing is added there. */
@media (min-width: 981px) {
  main > .c-section:first-child {
    padding-top: calc(var(--header-h) + var(--section-y));
  }
}

/* A section's opening words are centred, so a page is symmetrical whatever the
   block under them does. */
.c-section > .c-shell > h2,
.c-section > .c-shell > .c-lead {
  margin-inline: auto;
  text-align: center;
}

/* A heading followed straight by content needs the room the lead would have
   given it. */
.c-section > .c-shell > h2 {
  margin-bottom: var(--s-7);
}

.c-section > .c-shell > h2:has(+ .c-lead) {
  margin-bottom: var(--s-4);
}

.c-section > .c-shell > .c-lead {
  margin-bottom: var(--s-7);
}

.c-section > .c-shell > p {
  max-width: 68ch;
  margin-inline: auto;
}

.c-section > .c-shell > p + p {
  margin-top: var(--s-4);
}

/* Sections glide in once as they reach the screen. creator-site.js puts
   .can-reveal on <html> before it starts observing, exactly as the main site's
   app.js does, so a page without JavaScript is simply there, in full. Lite
   machines are left out by :not(.is-lite), the same gate the milestones use:
   they get every word at once, with nothing to transition. */
@media (prefers-reduced-motion: no-preference) {
  html.can-reveal:not(.is-lite) [data-reveal] {
    opacity: 0;
    transform: translate3d(0, 24px, 0);
    transition:
      opacity 800ms var(--ease-out),
      transform 1000ms var(--ease-out);
  }

  html.can-reveal:not(.is-lite) [data-reveal].is-in {
    opacity: 1;
    transform: none;
  }
}

/* --------------------------------------------------------------------------
   4. Type. One display voice (Anton, capitals) at a size each block sets in
   --fs, so section 24 can retune every heading for Russian, Georgian and
   Armenian in one rule. Anton has a single weight: anything but 400 is a fake
   bold, hence font-synthesis: none.
   -------------------------------------------------------------------------- */
.t-display {
  margin: 0;
  color: var(--c-text);
  font-family: "Prime Display", "Prime Intl", Impact, sans-serif;
  font-size: var(--fs, 2rem);
  font-weight: 400;
  font-synthesis: none;
  letter-spacing: 0.01em;
  line-height: 0.92;
  text-transform: uppercase;
  text-wrap: balance;
}

h1.t-display {
  --fs: clamp(3.5rem, 8vw, 7.5rem);
  letter-spacing: 0.005em;
  line-height: 0.9;
}

h2.t-display {
  --fs: clamp(2.5rem, 5vw, 4.5rem);
}

h3.t-display {
  --fs: clamp(1.5rem, 2.2vw, 2rem);
  letter-spacing: 0.02em;
  line-height: 1;
}

.c-lead {
  max-width: 60ch;
  color: var(--c-text);
  font-size: clamp(1.1rem, 1.5vw, 1.3rem);
  font-weight: 500;
  line-height: 1.55;
}

.c-meta {
  color: var(--c-dust);
  font-size: 0.84rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1.4;
}

.c-fine {
  color: var(--c-fine);
  font-size: 0.84rem;
  line-height: 1.5;
}

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

/* --------------------------------------------------------------------------
   5. The page sky. One fixed layer of plain gradients, taller than the screen,
   slid up by half a screen over the length of the page so it drifts slower than
   the content. Gradients only, painted once, moved by the compositor: no
   picture, no blur, no repaint. The same sky as playprimetanki.com, so walking
   between the two sites feels like one place.
   -------------------------------------------------------------------------- */
.c-body::before {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  z-index: 0;
  height: 150vh;
  content: "";
  background:
    radial-gradient(ellipse 62% 30% at 50% 0%, rgba(116, 166, 212, 0.2), transparent 72%),
    radial-gradient(ellipse 40% 26% at 0% 36%, rgba(236, 122, 34, 0.15), transparent 72%),
    radial-gradient(ellipse 36% 24% at 100% 26%, rgba(96, 152, 202, 0.11), transparent 72%),
    radial-gradient(ellipse 42% 28% at 100% 66%, rgba(230, 112, 28, 0.13), transparent 72%),
    radial-gradient(ellipse 48% 28% at 16% 90%, rgba(90, 144, 194, 0.12), transparent 72%),
    linear-gradient(180deg, #081320 0%, #050c15 52%, #03070d 100%);
  pointer-events: none;
  will-change: transform;
}

@keyframes c-sky-drift {
  to {
    transform: translate3d(0, -50vh, 0);
  }
}

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .c-body::before {
      animation: c-sky-drift linear both;
      animation-timeline: scroll(root block);
    }
  }
}

/* --------------------------------------------------------------------------
   6. The header. Desktop is the main site's glass, recipe for recipe: the blur
   lives on a pseudo-element and NEVER on .c-header itself, because a
   backdrop-filter on the bar would make it the containing block of the fixed
   menu sheet and collapse the whole menu into the bar. The pane runs 40px below
   the bar and thins out on an eased curve, under the words, never behind them:
   the mask below carries the blur and the tint out together, so the footage
   goes from frosted to clear by degrees with nothing switching off. This 80px
   bar is the one per-frame filter on the site, so it stays one layer: a second
   blurred band over the same strip would double what every scroll frame costs
   on the ordinary PCs this site is for. Touch devices and lite machines get a
   still, solid pane instead.
   -------------------------------------------------------------------------- */
.c-header {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  z-index: 30;
  display: flex;
  width: 100%;
  height: var(--header-h);
  align-items: center;
  gap: var(--s-3);
  padding-inline: max(24px, calc((100% - 1280px) / 2));
}

.c-header::before {
  position: absolute;
  inset: 0 0 -40px;
  z-index: -1;
  content: "";
  background: linear-gradient(180deg, rgba(4, 9, 15, 0.86), rgba(4, 9, 15, 0.7));
  -webkit-mask-image: linear-gradient(180deg, #000 66%, rgba(0, 0, 0, 0.72) 76%, rgba(0, 0, 0, 0.4) 86%, rgba(0, 0, 0, 0.14) 94%, transparent);
  mask-image: linear-gradient(180deg, #000 66%, rgba(0, 0, 0, 0.72) 76%, rgba(0, 0, 0, 0.4) 86%, rgba(0, 0, 0, 0.14) 94%, transparent);
  pointer-events: none;
}

/* With blur available the pane goes nearly clear: what tints it is mostly the
   footage behind it, blurred and a touch richer. */
@supports ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .c-header::before {
    background-color: rgba(4, 9, 15, 0.24);
    background-image: linear-gradient(180deg, rgba(3, 7, 12, 0.14), transparent 66%);
    -webkit-backdrop-filter: blur(16px) saturate(170%);
    backdrop-filter: blur(16px) saturate(170%);
  }
}

/* Over the hero the pane is nearly clear. Once the page itself scrolls under,
   white headings and bright pictures pass behind the menu, so the tint deepens
   over the first 60vh. A scroll-driven animation: it runs only while that range
   is being scrolled. */
@supports ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  @supports (animation-timeline: scroll()) {
    @media (min-width: 981px) {
      .c-header::before {
        animation: c-glass-tint linear both;
        animation-timeline: scroll(root block);
        animation-range: 0 60vh;
      }
    }
  }
}

@keyframes c-glass-tint {
  from {
    background-color: transparent;
  }
}

/* Refraction (Chromium): the backdrop is bent through a displacement map before
   the blur, so the footage warps as it passes under the pane, like light through
   thick glass. The pane is 120px tall at most; never reuse this on anything
   larger. */
@supports (backdrop-filter: url("#x")) {
  .c-header::before {
    -webkit-backdrop-filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='g' x='0' y='0' width='100%25' height='100%25' color-interpolation-filters='sRGB'><feTurbulence type='fractalNoise' baseFrequency='0.006 0.02' numOctaves='2' seed='7' result='n'/><feDisplacementMap in='SourceGraphic' in2='n' scale='18' xChannelSelector='R' yChannelSelector='G'/></filter></svg>#g") blur(10px) saturate(170%);
    backdrop-filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='g' x='0' y='0' width='100%25' height='100%25' color-interpolation-filters='sRGB'><feTurbulence type='fractalNoise' baseFrequency='0.006 0.02' numOctaves='2' seed='7' result='n'/><feDisplacementMap in='SourceGraphic' in2='n' scale='18' xChannelSelector='R' yChannelSelector='G'/></filter></svg>#g") blur(10px) saturate(170%);
  }
}

/* The brand: the game's name, then this site's half of it in the Gold Box gold. */
.c-wordmark {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  margin-inline-end: auto;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.6), 0 0 2px rgba(0, 0, 0, 0.35);
  white-space: nowrap;
}

.c-wordmark span {
  color: #f3f7fa;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: 0.34em;
  line-height: 1;
  text-transform: uppercase;
}

.c-wordmark b {
  color: var(--c-gold);
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.26em;
  line-height: 1;
  text-transform: uppercase;
}

.c-menu-toggle {
  display: none;
}

/* The menu sits in the middle of whatever room the brand and the controls leave. */
.c-nav {
  display: flex;
  align-self: stretch;
  align-items: center;
  gap: var(--s-1);
  margin-inline: auto;
}

/* Links in the glass bar: the pointer lights a soft pane behind the word, the
   same material as the bar itself. */
.c-nav a {
  position: relative;
  display: inline-flex;
  height: 42px;
  align-items: center;
  padding: 0 14px;
  border-radius: 999px;
  color: #b9c6d0;
  font-size: 0.9rem;
  font-weight: 820;
  letter-spacing: 0.1em;
  line-height: 1;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.6), 0 0 2px rgba(0, 0, 0, 0.35);
  text-transform: uppercase;
  transition:
    color var(--t-fast) ease,
    background-color var(--t-fast) ease,
    box-shadow var(--t-fast) ease;
}

.c-nav a:hover {
  background-color: rgba(255, 255, 255, 0.09);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
  color: #ffffff;
}

.c-nav a.is-here {
  background-color: rgba(245, 154, 50, 0.14);
  box-shadow: inset 0 0 0 1px rgba(245, 154, 50, 0.22);
  color: #ffffff;
}

.c-nav-discord:hover {
  background-color: var(--c-discord);
  box-shadow: inset 0 0 0 1px rgba(140, 149, 255, 0.5);
  color: #ffffff;
}

/* The pinned apply control. It appears only once the hero's own button has left
   the screen, so exactly one green button is ever in view. */
.c-header-apply {
  --fb-h: 40px;
  flex: none;
  opacity: 0;
  pointer-events: none;
  transform: translateY(-6px);
  transition:
    opacity var(--t-base) var(--ease-out),
    transform var(--t-base) var(--ease-out);
}

.c-header-apply.is-in {
  opacity: 1;
  pointer-events: auto;
  transform: none;
}

/* --------------------------------------------------------------------------
   7. Phone and tablet: a sticky solid bar with a full-screen menu sheet. The
   bar never carries a filter of its own here, for the containing-block reason
   above.
   -------------------------------------------------------------------------- */
@media (max-width: 980px) {
  :root {
    --gutter: 20px;
    --shell: min(100% - 40px, 900px);
    --header-h: 64px;
  }

  html {
    scroll-padding-top: 76px;
  }

  .c-header {
    position: sticky;
    top: 0;
    z-index: 40;
    padding-inline: var(--gutter);
    border-bottom: 1px solid rgba(196, 215, 231, 0.14);
    background: transparent;
    gap: var(--s-2);
  }

  .c-header::before {
    inset: 0;
    background: rgba(4, 9, 15, 0.94);
    -webkit-mask-image: none;
    mask-image: none;
  }

  @supports ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
    .c-header::before {
      background: rgba(5, 11, 18, 0.5);
    }
  }

  .c-wordmark {
    gap: 7px;
  }

  .c-wordmark span {
    font-size: 0.82rem;
    letter-spacing: 0.24em;
  }

  .c-wordmark b {
    font-size: 0.66rem;
    letter-spacing: 0.18em;
  }

  .c-menu-toggle {
    display: inline-flex;
    order: 3;
    min-width: 88px;
    min-height: 44px;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(243, 128, 26, 0.75);
    border-radius: var(--r-inner);
    background: rgba(7, 13, 20, 0.9);
    color: var(--c-orange-hi);
    cursor: pointer;
    font-size: 0.7rem;
    font-weight: 820;
    letter-spacing: 0.14em;
    text-transform: uppercase;
  }

  /* The sheet: the whole screen under the bar, one row per destination. */
  .c-nav {
    position: fixed;
    z-index: 39;
    display: none;
    inset: var(--header-h) 0 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin: 0;
    padding: 10px var(--gutter) calc(24px + env(safe-area-inset-bottom));
    overflow-y: auto;
    background: rgba(3, 8, 14, 0.97);
  }

  .c-nav.is-open {
    display: flex;
  }

  .c-nav a {
    display: flex;
    height: auto;
    min-height: 60px;
    align-items: center;
    padding: 0 6px;
    border-bottom: 1px solid rgba(180, 208, 229, 0.12);
    border-radius: 0;
    background: none;
    box-shadow: none;
    font-size: 1.15rem;
    letter-spacing: 0.06em;
  }

  .c-nav a.is-here {
    color: var(--c-orange-hi);
  }

  .c-nav-discord {
    color: var(--c-discord-light);
  }

  .c-nav-discord:hover {
    background: none;
    box-shadow: none;
  }

  .c-header-apply {
    order: 2;
  }
}

/* --------------------------------------------------------------------------
   8. The language switcher. lang.js draws it into .lang-switch on every page,
   so these are the main site's rules, carried over unchanged apart from the
   asset paths.
   -------------------------------------------------------------------------- */
.lang-switch {
  position: relative;
  flex: none;
  order: 4;
  /* lang.js fills this box, so its size is reserved: without it the header
     re-flows the moment the script runs. */
  min-width: 64px;
  min-height: 38px;
}

.lang-current {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 38px;
  padding: 0 10px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.07);
  color: #dbe6ef;
  cursor: pointer;
  font-family: inherit;
  font-size: 0.76rem;
  font-weight: 820;
  letter-spacing: 0.1em;
  transition: border-color var(--t-fast) ease, color var(--t-fast) ease;
}

.lang-current:hover,
.lang-switch.is-open .lang-current {
  border-color: rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.13);
  color: #ffffff;
}

.flag {
  flex: none;
  width: 20px;
  height: 20px;
  border-radius: var(--r-round);
  background-position: center;
  background-size: cover;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.32), 0 1px 3px rgba(0, 0, 0, 0.55);
}

/* The folder and the flag are the country (br, ge, am); the code is the
   language (pt, ka, hy). Both are right. */
.flag-en { background-image: url("/assets/flags/en.svg"); }
.flag-ka { background-image: url("/assets/flags/ka.svg"); }
.flag-ru { background-image: url("/assets/flags/ru.svg"); }
.flag-pt { background-image: url("/assets/flags/br.svg"); }
.flag-de { background-image: url("/assets/flags/de.svg"); }
.flag-hy { background-image: url("/assets/flags/am.svg"); }

.lang-caret {
  width: 0;
  height: 0;
  margin-left: 1px;
  border-top: 5px solid currentColor;
  border-right: 4px solid transparent;
  border-left: 4px solid transparent;
  opacity: 0.75;
  transition: transform 160ms ease;
}

.lang-switch.is-open .lang-caret {
  transform: rotate(180deg);
}

.lang-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 60;
  min-width: 128px;
  margin: 0;
  padding: 6px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 18px;
  background: rgba(8, 14, 22, 0.94);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.5);
  list-style: none;
}

/* A small pane of the bar's own glass: what is behind it shows through. */
@supports ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .lang-menu {
    background:
      linear-gradient(180deg, rgba(255, 255, 255, 0.06), transparent 40%),
      rgba(8, 14, 22, 0.58);
    -webkit-backdrop-filter: blur(22px) saturate(170%);
    backdrop-filter: blur(22px) saturate(170%);
  }
}

.lang-menu li + li {
  margin-top: 2px;
}

.lang-menu a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--r-control);
  color: #c8d5e0;
  font-size: 0.8rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  transition: background var(--t-fast) ease, color var(--t-fast) ease;
}

.lang-menu a:hover {
  background: rgba(255, 255, 255, 0.1);
  color: #ffffff;
}

.lang-menu a.is-current {
  background: linear-gradient(180deg, #f8a13a, #e0740f);
  color: #14100a;
}

/* "This page is also in your language": an offer, never a redirect. */
.lang-pill {
  position: fixed;
  right: 0;
  bottom: 18px;
  left: 0;
  z-index: 70;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: max-content;
  max-width: min(620px, calc(100% - 28px));
  margin-inline: auto;
  padding: 10px 12px;
  border: 1px solid rgba(196, 215, 231, 0.2);
  border-radius: 14px;
  background: rgba(7, 12, 19, 0.96);
  box-shadow: 0 22px 54px rgba(0, 0, 0, 0.62);
  opacity: 0;
  transform: translate(0, 18px);
  transition: opacity 220ms ease, transform 220ms ease;
}

.lang-pill.is-in {
  opacity: 1;
  transform: translate(0, 0);
}

.lang-pill-text {
  color: #dfe8f0;
  font-size: 0.92rem;
  line-height: 1.35;
}

.lang-pill-go {
  flex: none;
  padding: 8px 14px;
  border: 1px solid rgba(243, 128, 26, 0.85);
  border-radius: 9px;
  background: rgba(243, 128, 26, 0.14);
  color: var(--c-orange-hi);
  font-size: 0.88rem;
  font-weight: 800;
}

.lang-pill-go:hover {
  background: rgba(243, 128, 26, 0.24);
  color: #ffffff;
}

.lang-pill-x {
  flex: none;
  padding: 8px 4px;
  border: 0;
  background: none;
  color: #8ea1b3;
  cursor: pointer;
  font-family: inherit;
  font-size: 0.82rem;
}

.lang-pill-x:hover {
  color: #dfe8f0;
}

/* Georgian is a wider script with no capitals, and Russian and Armenian words
   run longer than English ones, so the tracking that suits English capitals is
   dialled back wherever text is set in uppercase. */
[lang="ka"] .c-nav a,
[lang="ru"] .c-nav a,
[lang="hy"] .c-nav a,
[lang="ka"] .c-form label,
[lang="ru"] .c-form label,
[lang="hy"] .c-form label,
[lang="ka"] .c-footer-bottom,
[lang="ru"] .c-footer-bottom,
[lang="hy"] .c-footer-bottom,
[lang="ka"] .c-menu-toggle,
[lang="ru"] .c-menu-toggle,
[lang="hy"] .c-menu-toggle,
[lang="ka"] .c-wordmark span,
[lang="ru"] .c-wordmark span,
[lang="hy"] .c-wordmark span,
[lang="ka"] .c-wordmark b,
[lang="ru"] .c-wordmark b,
[lang="hy"] .c-wordmark b {
  letter-spacing: 0.03em;
}

[lang="ka"] .c-nav a,
[lang="ru"] .c-nav a,
[lang="hy"] .c-nav a {
  padding: 0 12px;
  font-size: 0.88rem;
}

[lang="ka"] .fight-button,
[lang="hy"] .fight-button {
  font-size: 0.9em;
  font-weight: 700;
  letter-spacing: 0;
}

[lang="ka"] .c-lead,
[lang="ru"] .c-lead,
[lang="pt-BR"] .c-lead,
[lang="de"] .c-lead,
[lang="hy"] .c-lead {
  text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   9. The skip link.
   -------------------------------------------------------------------------- */
.skip-link {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 100;
  padding: 9px 13px;
  transform: translateY(-160%);
  border-radius: 3px;
  background: var(--c-orange-hi);
  color: #160b03;
  font-size: 1rem;
  font-weight: 850;
}

.skip-link:focus {
  transform: translateY(0);
}

/* --------------------------------------------------------------------------
   10. The hero. Real game footage under a static shade, dissolving into the
   page's sky through one mask. No filter on any layer: the only thing that
   moves is the art, and only by transform.
   -------------------------------------------------------------------------- */
.c-hero {
  position: relative;
  display: grid;
  min-height: min(88svh, 900px);
  align-content: center;
  padding-block: calc(var(--header-h) + var(--s-7)) var(--s-8);
  isolation: isolate;
  overflow: clip;
}

/* The poster, the video and their shade in one layer that fades out over its
   lower third, so the footage dissolves into the sky with no edge. */
.c-hero-media {
  position: absolute;
  inset: 0;
  z-index: -5;
  -webkit-mask-image: linear-gradient(180deg, #000 62%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 62%, transparent 100%);
  pointer-events: none;
}

/* The art is taller than the hero and anchored above it, so the parallax below
   can slide it down without ever showing an edge. */
.c-hero-media img,
.c-hero-media video {
  position: absolute;
  top: -18%;
  right: 0;
  left: 0;
  z-index: -5;
  width: 100%;
  height: 118%;
  max-width: none;
  object-fit: cover;
  object-position: 50% 40%;
}

/* creator-site.js loads the loop after the page has loaded and adds .is-in. */
.c-hero-media video {
  opacity: 0;
  transition: opacity 600ms ease;
}

.c-hero-media video.is-in {
  opacity: 1;
}

/* Three static gradients: a pool of shade under the words, a vignette, and the
   fade into the page. Nothing here animates and nothing is blurred. */
.c-hero-shade {
  position: absolute;
  inset: 0;
  z-index: -4;
  background:
    radial-gradient(ellipse 44% 46% at 50% 44%, rgba(3, 8, 14, 0.66), rgba(3, 8, 14, 0.46) 55%, rgba(3, 8, 14, 0.2)),
    radial-gradient(ellipse 120% 90% at 50% 40%, transparent 55%, rgba(2, 5, 8, 0.6)),
    linear-gradient(180deg, transparent 58%, rgba(5, 13, 22, 0.72));
  pointer-events: none;
}

/* Film grain over the footage only. It is a background image, baked once by the
   rasteriser from this tile, not a live filter: nothing is re-computed on
   scroll. 128px tile, stitched, so it repeats without a seam. */
.c-grain {
  position: absolute;
  inset: 0;
  z-index: -3;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='128' height='128'><filter id='n' x='0' y='0' width='100%25' height='100%25'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/></filter><rect width='128' height='128' filter='url(%23n)'/></svg>");
  background-repeat: repeat;
  background-size: 128px 128px;
  opacity: 0.06;
  pointer-events: none;
}

.c-hero-copy {
  width: var(--shell);
  margin-inline: auto;
  text-align: center;
}

/* When a page opens with its title and lead and then goes straight into content,
   the content needs the room a section break would have given it. */
.c-hero-copy:not(:last-child) {
  margin-bottom: var(--s-7);
}

.c-hero-copy h1 {
  max-width: 18ch;
  margin-inline: auto;
}

/* It sits over footage, so it carries its own contrast. */
.c-hero-copy .c-lead {
  max-width: 46ch;
  margin: var(--s-5) auto 0;
  color: #e8eef4;
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.85), 0 4px 14px rgba(0, 0, 0, 0.9);
}

.c-hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin-top: var(--s-6);
}

/* Parallax: the art lags the page by about a third. A scroll-driven transform,
   run by the compositor, off on lite machines and with reduced motion. */
@keyframes c-hero-drift {
  to {
    transform: translate3d(0, 18%, 0);
  }
}

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    html:not(.is-lite) .c-hero-media img,
    html:not(.is-lite) .c-hero-media video {
      animation: c-hero-drift linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 100vh;
      will-change: transform;
    }
  }
}

/* --------------------------------------------------------------------------
   11. The counters. One plate that overlaps the hero, three numbers, no rules
   between them. Every number here is a real one from the feed: the HTML holds
   the final value, so it is right with no JavaScript at all.
   -------------------------------------------------------------------------- */
.c-stats {
  position: relative;
  z-index: 2;
  display: grid;
  margin-top: -56px;
  padding: clamp(24px, 3vw, 36px);
  gap: var(--s-5);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  text-align: center;
}

.c-stat {
  display: grid;
  gap: var(--s-2);
  justify-items: center;
  min-width: 0;
}

/* The count-up must not re-flow the plate as the digits grow, so the box is at
   least as wide as the final number: creator-site.js sets --c-chars from the
   final string, and 1ch is Anton's digit width. */
.c-stat-num {
  --fs: clamp(2.75rem, 5vw, 4.5rem);
  display: inline-block;
  min-width: calc(var(--c-chars, 3) * 1ch);
  letter-spacing: 0;
  line-height: 0.9;
}

.c-stat-label {
  color: var(--c-body);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1.35;
}

/* --------------------------------------------------------------------------
   12. Plates. One surface for every card, row tray, FAQ item and form card: a
   lit top bevel, a dark lip, a hairline edge and a deep shadow. Six pixels of
   radius, never more.
   -------------------------------------------------------------------------- */
.c-plate {
  position: relative;
  border-radius: var(--r-plate);
  background: var(--c-plate);
  box-shadow: var(--sh-plate);
}

/* --------------------------------------------------------------------------
   13. Tier cards. They wrap and stay centred, so an odd card sits in the middle
   of the last row instead of hanging off one side. No ribbons, no tier numbers,
   no price-table checkmarks.
   -------------------------------------------------------------------------- */
.c-tiers {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-4);
}

.c-tier {
  display: flex;
  flex: 0 1 calc((100% - 2 * var(--s-4)) / 3);
  min-width: 280px;
  flex-direction: column;
  padding-bottom: var(--s-5);
  isolation: isolate;
  overflow: hidden;
  transition: transform var(--t-base) var(--ease-expo), box-shadow var(--t-base) ease;
}

/* The lift's shadow rides a pseudo-element's opacity, so no box-shadow is ever
   animated. */
.c-tier::before {
  position: absolute;
  inset: 0;
  z-index: -1;
  content: "";
  border-radius: inherit;
  box-shadow: var(--sh-lift);
  opacity: 0;
  transition: opacity var(--t-base) var(--ease-expo);
}

.c-tier:hover,
.c-tier:focus-within {
  box-shadow:
    inset 0 1px 0 var(--c-edge-lit),
    inset 0 -1px 0 var(--c-edge-dark),
    inset 0 0 0 1px rgba(245, 154, 50, 0.54),
    0 24px 55px rgba(0, 0, 0, 0.34);
  transform: translateY(-5px);
}

.c-tier:hover::before,
.c-tier:focus-within::before {
  opacity: 1;
}

/* A band of real map, graded and masked in the file, never by a CSS filter. */
.c-tier-art {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: var(--r-plate) var(--r-plate) 0 0;
  -webkit-mask-image: linear-gradient(180deg, #000 55%, transparent);
  mask-image: linear-gradient(180deg, #000 55%, transparent);
}

.c-tier-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The insignia hangs over the band's lower edge. Its shadow is baked in. */
.c-tier-badge {
  margin: -30px 0 0 var(--s-5);
}

.c-tier-badge img {
  width: 52px;
  height: 52px;
  object-fit: contain;
}

.c-tier-name {
  margin: var(--s-3) var(--s-5) 0;
}

.c-tier-req {
  margin: var(--s-2) var(--s-5) 0;
  color: var(--c-dust);
  font-size: 0.95rem;
  line-height: 1.5;
}

.c-tier-req b {
  color: var(--c-text);
  font-weight: 800;
}

.c-tier-list {
  display: grid;
  gap: 10px;
  margin: var(--s-4) var(--s-5) 0;
}

.c-tier-list li {
  position: relative;
  padding-left: 20px;
  color: var(--c-body);
  font-size: 1rem;
  line-height: 1.5;
}

/* A mark, not a tick: a checkmark list is the pricing-table cliché. */
.c-tier-list li::before {
  position: absolute;
  top: 0.62em;
  left: 0;
  width: 6px;
  height: 6px;
  content: "";
  transform: rotate(45deg);
  background: var(--c-orange);
}

/* The top tier: gold on the edge and the name, and nowhere else. */
.c-tier.is-top {
  box-shadow:
    inset 0 1px 0 rgba(250, 234, 165, 0.35),
    inset 0 -1px 0 var(--c-edge-dark),
    inset 0 0 0 1px rgba(212, 166, 63, 0.55),
    0 24px 55px rgba(0, 0, 0, 0.34);
}

.c-tier.is-top .c-tier-name {
  color: var(--c-gold);
}

.c-tier.is-top:hover,
.c-tier.is-top:focus-within {
  box-shadow:
    inset 0 1px 0 rgba(250, 234, 165, 0.45),
    inset 0 -1px 0 var(--c-edge-dark),
    inset 0 0 0 1px rgba(212, 166, 63, 0.8),
    0 24px 55px rgba(0, 0, 0, 0.34),
    var(--glow-gold);
}

/* --------------------------------------------------------------------------
   14. Reward blocks. Grouped by where the reward lands (in the game, for the
   players you bring, beyond the game). They are statements, not links: they do
   not lift and they do not pretend to be clickable. Where the reward lands is
   carried by the section it sits in, each with its own heading: no page wraps
   the blocks in a group, so there are no group rules here.
   -------------------------------------------------------------------------- */

/* Two plates of prose under a section lead: the same surface as everything else,
   but body text, not the small meta type a tier card uses. */
.c-points {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-top: var(--s-7);
}

.c-point {
  display: grid;
  gap: var(--s-3);
  align-content: start;
  padding: clamp(24px, 3vw, 36px);
}

.c-point h3 {
  --fs: clamp(1.4rem, 2vw, 1.9rem);
}

.c-point p {
  margin: 0;
  color: var(--c-body);
  font-size: 1.02rem;
  line-height: 1.65;
}

/* Flex, not a three-column grid: a row that is not full stays centred under the
   others instead of hugging the left edge (the owner's centring rule). */
.c-rewards {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  justify-content: center;
}

.c-rewards > .c-reward {
  flex: 0 1 calc((100% - 2 * var(--s-4)) / 3);
  min-width: 260px;
}

.c-reward {
  display: grid;
  gap: var(--s-2);
  align-content: start;
  justify-items: center;
  padding: var(--s-5);
  text-align: center;
}

.c-reward-art {
  display: grid;
  min-height: 90px;
  align-items: end;
  margin-bottom: var(--s-2);
}

.c-reward-art img {
  width: auto;
  max-width: 100%;
  height: 90px;
  object-fit: contain;
}

.c-reward-value {
  --fs: clamp(2.5rem, 4vw, 3.5rem);
  letter-spacing: 0;
  line-height: 0.95;
}

.c-reward-name {
  color: var(--c-text);
  font-size: 1.05rem;
  font-weight: 800;
  line-height: 1.35;
}

.c-reward-note {
  color: var(--c-body);
  font-size: 0.95rem;
  line-height: 1.55;
}

/* --------------------------------------------------------------------------
   15. The step route. Order is carried by the list itself and shown by a
   chevron between the steps: a direction mark, not a divider line, and never a
   numbered circle.
   -------------------------------------------------------------------------- */
.c-route {
  display: grid;
  gap: var(--s-7);
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.c-route-step {
  position: relative;
}

.c-route-step + .c-route-step::before {
  position: absolute;
  top: 0.9em;
  left: -29px;
  width: 10px;
  height: 10px;
  content: "";
  transform: rotate(45deg);
  border-top: 2px solid var(--c-edge-strong);
  border-right: 2px solid var(--c-edge-strong);
}

.c-route-step h3 {
  margin-bottom: var(--s-3);
}

.c-route-step p {
  color: var(--c-body);
  font-size: 1rem;
  line-height: 1.6;
}

/* --------------------------------------------------------------------------
   16. The application form. One centred card per stage: the form, the sent
   message, the honest failure. Stages are swapped with the hidden attribute.
   -------------------------------------------------------------------------- */
.c-form-stage {
  display: grid;
  width: min(640px, 100%);
  margin-inline: auto;
  padding: 34px;
  gap: var(--s-4);
}

.c-form {
  gap: 14px 16px;
}

.c-field {
  display: grid;
  gap: 6px;
  min-width: 0;
}

.c-field-row {
  display: grid;
  gap: 14px 16px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.c-form label {
  color: #93a3ae;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  line-height: 1.3;
  text-transform: uppercase;
}

.c-form input,
.c-form select,
.c-form textarea {
  width: 100%;
  min-height: 52px;
  padding: 13px 15px;
  border: 1px solid var(--c-edge);
  border-radius: var(--r-control);
  background: var(--c-field);
  color: var(--c-text);
  font-family: inherit;
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.4;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}

.c-form textarea {
  min-height: 140px;
  resize: vertical;
}

/* The select's own arrow, drawn in two gradients so no image is needed. */
.c-form select {
  appearance: none;
  padding-right: 44px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--c-muted) 50%),
    linear-gradient(135deg, var(--c-muted) 50%, transparent 50%);
  background-position: calc(100% - 26px) calc(50% + 1px), calc(100% - 20px) calc(50% + 1px);
  background-repeat: no-repeat;
  background-size: 6px 6px, 6px 6px;
}

.c-form input::placeholder,
.c-form textarea::placeholder {
  color: var(--c-fine);
}

.c-form input:hover,
.c-form select:hover,
.c-form textarea:hover {
  border-color: var(--c-edge-strong);
}

/* The field lights up, and the ring stays. A warm border and a soft halo say
   "this one is live"; they are not a focus indicator, because a colour change
   alone is what a keyboard user loses track of first. The ring is the site's
   own, the same 3px of --c-orange-hi at the same offset as every other control,
   so nothing here ever sets outline: none. */
.c-form input:focus,
.c-form select:focus,
.c-form textarea:focus {
  border-color: rgba(243, 128, 26, 0.8);
  box-shadow: 0 0 0 3px rgba(243, 120, 20, 0.16);
}

.c-form input:focus-visible,
.c-form select:focus-visible,
.c-form textarea:focus-visible {
  outline: 3px solid var(--c-orange-hi);
  outline-offset: 3px;
}

.c-form input:disabled,
.c-form select:disabled,
.c-form textarea:disabled {
  cursor: default;
  opacity: 0.55;
}

.c-form input[aria-invalid="true"],
.c-field:has(.c-field-status.is-err) input,
.c-field:has(.c-field-status.is-err) select,
.c-field:has(.c-field-status.is-err) textarea {
  border-color: rgba(255, 143, 122, 0.6);
}

.c-field:has(.c-field-status.is-ok) input {
  border-color: rgba(111, 220, 154, 0.55);
}

.c-field-hint {
  color: var(--c-fine);
  font-size: 0.84rem;
  line-height: 1.45;
}

.c-field-status {
  font-size: 0.92rem;
  font-weight: 700;
  line-height: 1.4;
}

.c-field-status.is-err {
  color: var(--c-down);
}

.c-field-status.is-ok {
  color: var(--c-up);
}

.c-form .cf-turnstile,
.c-form-stage .cf-turnstile {
  margin-top: var(--s-2);
}

.c-form-stage p {
  color: var(--c-body);
  font-size: 1.05rem;
  line-height: 1.6;
}

.c-form-stage h2,
.c-form-stage h3 {
  margin-bottom: var(--s-1);
}

/* --------------------------------------------------------------------------
   17. The leaderboard. Counts only, never a player's name. Rows are trays with
   4px between them, not ruled lines. The metals are the ratings site's, which
   the owner has already reviewed, and each element wears one metal cue only.
   -------------------------------------------------------------------------- */

/* Tabs: a well with two buttons, centred over the board. */
.c-board-tabs {
  display: flex;
  width: fit-content;
  min-height: 44px;
  align-items: center;
  gap: var(--s-1);
  margin: 0 auto var(--s-5);
  padding: var(--s-1);
  border-radius: var(--r-control);
  background: var(--c-plate);
  box-shadow: inset 0 0 0 1px var(--c-edge);
}

.c-board-tabs button {
  min-height: 36px;
  padding: 0 18px;
  border: 0;
  border-radius: var(--r-inner);
  background: none;
  color: var(--c-muted);
  cursor: pointer;
  font-size: 0.92rem;
  font-weight: 800;
  line-height: 1;
  transition: background-color var(--t-fast) ease, color var(--t-fast) ease, box-shadow var(--t-fast) ease;
}

.c-board-tabs button:hover {
  color: var(--c-text);
}

/* Two buttons that stay pressed, not a tablist: creator-site.js keeps them in
   sync with aria-pressed, which is also what the state is read out as. */
.c-board-tabs button[aria-pressed="true"] {
  background-color: rgba(245, 154, 50, 0.14);
  box-shadow: inset 0 0 0 1px rgba(245, 154, 50, 0.35);
  color: var(--c-orange-hi);
}

.c-board {
  display: grid;
  gap: var(--s-1);
  grid-template-columns: minmax(0, 1fr);
}

/* While the feed is in flight the board says nothing at all: no shimmer, no
   skeleton bars pretending to be data, and above all not the "nothing to show
   yet" line, which is an answer and would be read as one a moment before the
   real answer replaces it. The tabs go with it, because a range switch over an
   empty board does nothing. creator-site.js puts .is-loading on [data-board]
   for as long as the fetch is out. The room is held so the page does not jump
   when the rows land. */
[data-board].is-loading {
  min-height: var(--s-9);
}

[data-board].is-loading [data-board-empty],
[data-board].is-loading .c-board-tabs {
  display: none;
}

/* The alphabetical fallback: creator-site.js adds .is-roster when it has names
   but no counts. Those rows carry no place and no number, so the column the
   place would sit in is closed up rather than left as an empty indent in front
   of every face. An auto track keeps one rule right at every width, where the
   face is 48, 40 or 36px. */
.c-board.is-roster .c-row {
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "face name";
}

/* ---- The champion card ---- */
.c-champion {
  position: relative;
  display: grid;
  min-height: 260px;
  align-items: center;
  margin-bottom: var(--s-3);
  padding: clamp(24px, 4vw, 44px);
  gap: var(--s-2) clamp(20px, 3vw, 36px);
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "face name   metric"
    "face links  lead";
  isolation: isolate;
  overflow: hidden;
  border-radius: var(--r-plate);
  background:
    radial-gradient(ellipse 60% 120% at 0 0, rgba(212, 166, 63, 0.2), transparent 60%),
    linear-gradient(180deg, #16202b, #0b1118);
  box-shadow:
    inset 0 0 0 1px rgba(212, 166, 63, 0.45),
    inset 0 1px 0 rgba(250, 234, 165, 0.35),
    0 34px 80px rgba(0, 0, 0, 0.5),
    var(--glow-gold);
}

/* The name wears the game's own gold numeral, and the channels sit under it. */
.c-champion-title {
  display: flex;
  align-items: center;
  gap: clamp(12px, 1.6vw, 20px);
  grid-area: name;
  min-width: 0;
}

.c-champion-medal {
  width: auto;
  height: clamp(44px, 5vw, 68px);
  flex: none;
}

.c-champion-side {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  grid-area: links;
  min-width: 0;
  flex-wrap: wrap;
}

/* Real footage, masked so it never sits under the name. */
.c-champion-art {
  position: absolute;
  inset: 0;
  z-index: -1;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 45%);
  mask-image: linear-gradient(90deg, transparent, #000 45%);
  pointer-events: none;
}

.c-champion-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.22;
}

.c-champion-face {
  display: grid;
  width: 160px;
  height: 160px;
  grid-area: face;
  place-items: center;
  border: 3px solid var(--c-void);
  border-radius: var(--r-round);
  background: linear-gradient(145deg, #2b3f52, #111c27);
  box-shadow: 0 0 0 3px var(--c-gold-mid), 0 16px 32px rgba(0, 0, 0, 0.55);
  color: #ffffff;
  font-size: 4rem;
  font-weight: 900;
  object-fit: cover;
}

/* Scoped past h3.t-display: a champion's name is the biggest word on the page,
   not a plate heading. */
.c-champion .c-champion-name {
  --fs: clamp(2.5rem, 5vw, 4rem);
  grid-area: name;
  line-height: 0.95;
  /* a nickname keeps the case its owner typed */
  text-transform: none;
}

.c-champion .c-row-links {
  grid-area: links;
}

.c-champion-metric {
  --fs: clamp(3.5rem, 7vw, 6rem);
  grid-area: metric;
  justify-self: end;
  letter-spacing: 0;
  line-height: 0.88;
  text-align: right;
}

.c-champion-metric span {
  display: block;
  color: var(--c-dust);
  font-family: "Prime Text", "Prime Intl", Arial, sans-serif;
  font-size: 0.84rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: none;
}

/* A single pass of light across the plate, once as it arrives and again on
   hover. Never a loop.

   One pass, two pseudo-elements: ::after is the arrival and ::before is the
   hover. They cannot be the same element, because a hover that only changed the
   timing of an animation already running under the same name would not restart
   it, and handing the hover its own name would replay the arrival every time
   the pointer left again. Separate elements, one set of keyframes, no class to
   set: the card is built by creator-site.js, so ::after starts the moment the
   card is put on the page, which is exactly when it arrives. */
.c-champion::before,
.c-champion::after {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 0;
  width: 40%;
  content: "";
  transform: translateX(-100%) skewX(-18deg);
  background: linear-gradient(90deg, transparent, rgba(250, 234, 165, 0.18) 50%, transparent);
  opacity: 0;
  pointer-events: none;
}

@keyframes c-shine {
  0% {
    opacity: 0;
    transform: translateX(-100%) skewX(-18deg);
  }

  12% {
    opacity: 1;
  }

  88% {
    opacity: 1;
  }

  100% {
    opacity: 0;
    transform: translateX(260%) skewX(-18deg);
  }
}

@media (prefers-reduced-motion: no-preference) {
  html:not(.is-lite) .c-champion::after {
    animation: c-shine 1200ms cubic-bezier(0.4, 0, 0.2, 1) 400ms 1 both;
  }
}

@media (prefers-reduced-motion: no-preference) and (hover: hover) and (pointer: fine) {
  html:not(.is-lite) .c-champion:hover::before {
    animation: c-shine 1200ms cubic-bezier(0.4, 0, 0.2, 1) 1;
  }
}

/* ---- Rows ---- */
.c-row {
  display: grid;
  min-height: 56px;
  align-items: center;
  padding: var(--s-2) var(--s-4);
  gap: 6px var(--s-3);
  grid-template-columns: 3rem 48px minmax(0, 1fr) auto auto auto;
  grid-template-areas:
    "pos face name links move metric"
    "pos face gap  gap   gap  gap";
  border-radius: var(--r-plate);
  background: rgba(14, 20, 27, 0.72);
  content-visibility: auto;
  contain-intrinsic-size: auto 56px;
  transition: background-color var(--t-fast) ease;
}

.c-row:hover {
  background: var(--c-plate-up);
}

/* Placement belongs to the row and nowhere else. These classes are reused
   outside it (a metric in a hall-of-fame card, a face in the ticker), and a
   grid-area naming an area that does not exist there would build implicit
   tracks and overlap the card's own contents. */
.c-row > .c-row-pos { grid-area: pos; }
.c-row > .c-face { grid-area: face; }
.c-row > .c-row-name { grid-area: name; }
.c-row > .c-row-links { grid-area: links; }
.c-row > .c-move { grid-area: move; justify-self: end; }
.c-row > .c-row-metric { grid-area: metric; justify-self: end; }

.c-row-pos {
  color: var(--c-muted);
  font-size: 1rem;
  font-weight: 800;
}

.c-face {
  display: grid;
  width: 48px;
  height: 48px;
  place-items: center;
  border: 2px solid var(--c-void);
  border-radius: var(--r-round);
  background: linear-gradient(145deg, #2b3f52, #111c27);
  box-shadow: 0 0 0 1px var(--c-edge-strong), 0 8px 18px rgba(0, 0, 0, 0.5);
  object-fit: cover;
}

/* No photo yet: the first letter of the name, the same as the main site's
   creator pages. */
.c-face--letter {
  color: #ffffff;
  font-size: 1.3rem;
  font-weight: 900;
  line-height: 1;
}

.c-row-name {
  overflow: hidden;
  color: var(--c-text);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A creator's channels: each one its own logo in a round button. */
.c-row-links {
  display: flex;
  align-items: center;
  gap: var(--s-2);
}

.c-row-links a {
  display: inline-grid;
  width: 32px;
  height: 32px;
  place-items: center;
  border: 1px solid var(--c-edge);
  border-radius: var(--r-round);
  background-color: rgba(255, 255, 255, 0.04);
  color: #9fb0bc;
  transition:
    background-color 160ms ease,
    border-color 160ms ease,
    color 160ms ease,
    box-shadow 160ms ease,
    transform 160ms ease;
}

.c-row-links a::before {
  width: 15px;
  height: 15px;
  content: "";
  background-color: currentColor;
  -webkit-mask: var(--social-logo) no-repeat center / contain;
  mask: var(--social-logo) no-repeat center / contain;
}

/* Two hooks for the same thing: data-platform, and the .social-<key> class the
   main site's footer already uses, because that is the shape creator-site.js
   builds. Whichever the markup carries, the logo arrives. Twitch has no file in
   /assets yet, so it falls through to the worded button below. */
.c-row-links a[data-platform="youtube"],
.c-row-links a.social-youtube { --social-logo: url("/assets/social-youtube.svg"); }
.c-row-links a[data-platform="tiktok"],
.c-row-links a.social-tiktok { --social-logo: url("/assets/social-tiktok.svg"); }
.c-row-links a[data-platform="kick"],
.c-row-links a.social-kick { --social-logo: url("/assets/social-kick.svg"); }
.c-row-links a[data-platform="discord"],
.c-row-links a.social-discord { --social-logo: url("/assets/nav-discord.svg"); }
.c-row-links a[data-platform="facebook"],
.c-row-links a.social-facebook { --social-logo: url("/assets/social-facebook.svg"); }

.c-row-links a:hover {
  border-color: transparent;
  color: #ffffff;
  transform: translateY(-2px);
}

.c-row-links a[data-platform="youtube"]:hover,
.c-row-links a.social-youtube:hover {
  background-color: #ff0000;
  box-shadow: 0 8px 20px rgba(255, 0, 0, 0.35);
}

.c-row-links a[data-platform="tiktok"]:hover,
.c-row-links a.social-tiktok:hover {
  background-color: #000000;
  box-shadow: -2px 0 0 #25f4ee, 2px 0 0 #fe2c55, 0 8px 20px rgba(0, 0, 0, 0.5);
}

.c-row-links a[data-platform="kick"]:hover,
.c-row-links a.social-kick:hover {
  background-color: #53fc18;
  box-shadow: 0 8px 20px rgba(83, 252, 24, 0.3);
  color: #0b0e0f;
}

.c-row-links a[data-platform="discord"]:hover,
.c-row-links a.social-discord:hover {
  background-color: var(--c-discord);
  box-shadow: 0 8px 20px rgba(88, 101, 242, 0.4);
}

.c-row-links a[data-platform="facebook"]:hover,
.c-row-links a.social-facebook:hover {
  background-color: #0866ff;
  box-shadow: 0 8px 20px rgba(8, 102, 255, 0.4);
}

/* A channel we have no logo for (Twitch today) is a small word instead of a
   blank circle. */
.c-row-links a:not([data-platform], .social-youtube, .social-tiktok, .social-kick, .social-discord, .social-facebook) {
  width: auto;
  height: 32px;
  padding: 0 12px;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* and no empty square where its logo would have been */
.c-row-links a:not([data-platform], .social-youtube, .social-tiktok, .social-kick, .social-discord, .social-facebook)::before {
  content: none;
}

.c-row-metric {
  color: var(--c-text);
  font-size: 1rem;
  font-weight: 700;
}

/* Second and third: bigger and lit from the lead edge, the way the ratings site
   does it. One metal cue each, plus the medal on the position. */
.c-row.is-second {
  min-height: 72px;
  background:
    linear-gradient(90deg, rgba(185, 198, 212, 0.13), rgba(185, 198, 212, 0.03) 45%, transparent),
    var(--c-plate);
  box-shadow: inset 3px 0 0 var(--c-silver), 0 0 20px -9px rgba(185, 198, 212, 0.22);
  contain-intrinsic-size: auto 72px;
}

.c-row.is-third {
  min-height: 64px;
  background:
    linear-gradient(90deg, rgba(201, 146, 94, 0.12), rgba(201, 146, 94, 0.03) 45%, transparent),
    var(--c-plate);
  box-shadow: inset 2px 0 0 var(--c-bronze), 0 0 20px -9px rgba(201, 146, 94, 0.2);
  contain-intrinsic-size: auto 64px;
}

.c-row.is-second .c-row-name {
  font-size: 1.25rem;
}

.c-row.is-third .c-row-name {
  font-size: 1.125rem;
}

.c-row.is-second .c-row-pos,
.c-row.is-third .c-row-pos {
  display: grid;
  place-items: center;
  border-radius: var(--r-round);
  background: radial-gradient(circle at 32% 28%, var(--m-hi), var(--m) 58%, var(--m-deep));
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.5),
    inset 0 -2px 2px rgba(0, 0, 0, 0.25),
    0 2px 6px -2px rgba(0, 0, 0, 0.7);
  color: #141d29;
  font-family: "Prime Display", "Prime Intl", Impact, sans-serif;
  font-weight: 400;
  font-synthesis: none;
  line-height: 1;
}

.c-row.is-second .c-row-pos {
  --m-hi: var(--c-silver-hi);
  --m: var(--c-silver);
  --m-deep: var(--c-silver-deep);
  width: 36px;
  height: 36px;
  font-size: 1.5rem;
}

.c-row.is-third .c-row-pos {
  --m-hi: var(--c-bronze-hi);
  --m: var(--c-bronze);
  --m-deep: var(--c-bronze-deep);
  width: 32px;
  height: 32px;
  font-size: 1.35rem;
}

/* ---- Movement since last month ---- */
.c-move {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  font-size: 0.8rem;
  font-weight: 700;
  line-height: 1;
}

.c-move::before {
  width: 0;
  height: 0;
  content: "";
  border-inline: 5px solid transparent;
}

.c-move--up {
  color: var(--c-up);
}

.c-move--up::before {
  border-bottom: 7px solid currentColor;
}

.c-move--down {
  color: var(--c-down);
}

.c-move--down::before {
  border-top: 7px solid currentColor;
}

.c-move--same {
  color: var(--c-fine);
}

.c-move--same::before {
  width: 8px;
  height: 2px;
  border: 0;
  background: currentColor;
}

/* A creator who was not on the board last month: the word, no arrow. */
.c-move--new {
  color: var(--c-orange-hi);
}

.c-move--new::before {
  content: none;
}

/* ---- Nothing to show yet ---- */
.c-board-empty {
  padding: clamp(24px, 4vw, 40px);
  color: var(--c-body);
  font-size: 1.05rem;
  line-height: 1.6;
  text-align: center;
}

.c-board-empty p + p {
  margin-top: var(--s-3);
}

/* ---- Hall of fame: the winner of each month, kept for good ---- */
.c-hof {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-4);
}

/* A record, not a door: creator-site.js builds each card as a list item with no
   link in it, so it does not lift, glow or answer the pointer at all. The lift
   that used to be written here was hung on a.c-hof-card and could never match. */
.c-hof-card {
  display: grid;
  width: 200px;
  gap: var(--s-2);
  justify-items: center;
  padding: var(--s-5) var(--s-4);
  text-align: center;
}

.c-hof-card .c-face {
  width: 72px;
  height: 72px;
  box-shadow: 0 0 0 3px var(--c-gold-mid), 0 16px 32px rgba(0, 0, 0, 0.55);
}

.c-hof-card .c-face--letter {
  font-size: 2rem;
}

.c-hof-card .t-display {
  --fs: 1.5rem;
  text-transform: none;
}

/* ---- Milestones ---- */
/* They wrap and stay centred, so five of them sit in the middle of the page
   rather than filling the first five of nine equal tracks. */
.c-milestones {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-5) var(--s-4);
}

.c-milestone {
  display: grid;
  flex: 0 1 130px;
  gap: 6px;
  justify-items: center;
  text-align: center;
}

/* Every one of them at full strength. This page is the same for everybody: the
   marks are thresholds the board counts towards, not a record of what any one
   reader has reached, so there is no locked state to draw and nothing on the
   site that could set one. A dim for "not yet" and a gold ring for "unlocked"
   were written here for a per-creator view that does not exist, and the dim
   was what everybody actually got, on all five, for good. */
.c-milestone img {
  width: 52px;
  height: 52px;
  object-fit: contain;
}

.c-milestone strong {
  color: var(--c-text);
  font-size: 0.95rem;
  font-weight: 800;
  line-height: 1.3;
}

.c-milestone span {
  color: var(--c-fine);
  font-size: 0.84rem;
  line-height: 1.35;
}

/* They arrive with the section, one after another. */
@media (prefers-reduced-motion: no-preference) {
  html.can-reveal:not(.is-lite) [data-reveal] .c-milestone {
    opacity: 0.12;
    transform: scale(0.86);
    transition:
      opacity 520ms var(--ease-snap),
      transform 520ms var(--ease-snap);
  }

  html.can-reveal:not(.is-lite) [data-reveal].is-in .c-milestone {
    opacity: 1;
    transform: none;
  }

  .c-milestone:nth-child(2) { transition-delay: 40ms; }
  .c-milestone:nth-child(3) { transition-delay: 80ms; }
  .c-milestone:nth-child(4) { transition-delay: 120ms; }
  .c-milestone:nth-child(5) { transition-delay: 160ms; }
  .c-milestone:nth-child(6) { transition-delay: 200ms; }
  .c-milestone:nth-child(7) { transition-delay: 240ms; }
  .c-milestone:nth-child(n + 8) { transition-delay: 280ms; }
}

/* --------------------------------------------------------------------------
   18. The FAQ. Native details and summary, so it works before the script runs.
   Only the caret turns and the answer fades: no height animation, nothing to
   jank.
   -------------------------------------------------------------------------- */
.c-faq {
  display: grid;
  max-width: 820px;
  gap: var(--s-2);
  margin-inline: auto;
}

.c-faq-item summary {
  display: flex;
  min-height: 64px;
  align-items: center;
  justify-content: space-between;
  padding: 18px 22px;
  gap: var(--s-4);
  color: var(--c-text);
  cursor: pointer;
  font-size: 1.125rem;
  font-weight: 800;
  line-height: 1.35;
  list-style: none;
}

.c-faq-item summary::-webkit-details-marker {
  display: none;
}

.c-faq-caret {
  width: 0;
  height: 0;
  flex: none;
  border-top: 6px solid var(--c-orange);
  border-right: 5px solid transparent;
  border-left: 5px solid transparent;
  opacity: 0.85;
  transition: transform 160ms ease;
}

.c-faq-item[open] {
  background: var(--c-plate-up);
  box-shadow:
    inset 0 1px 0 var(--c-edge-lit),
    inset 0 -1px 0 var(--c-edge-dark),
    inset 0 0 0 1px rgba(245, 154, 50, 0.35),
    0 24px 55px rgba(0, 0, 0, 0.34);
}

.c-faq-item[open] .c-faq-caret {
  transform: rotate(180deg);
}

.c-faq-body {
  max-width: 68ch;
  padding: 0 22px 20px;
  color: var(--c-body);
  font-size: 1.02rem;
  line-height: 1.65;
}

.c-faq-body p + p {
  margin-top: var(--s-3);
}

@media (prefers-reduced-motion: no-preference) {
  .c-faq-item[open] .c-faq-body {
    animation: c-fade-in 160ms ease-out both;
  }
}

@keyframes c-fade-in {
  from {
    opacity: 0;
  }
}

/* --------------------------------------------------------------------------
   19. Buttons.

   The main action wears the original 2014 tankionline.com FIGHT! button, cut
   from that site's own sprite: the real left and right ends plus a piece of the
   textured middle, tiled. The word was drawn into the original picture, so here
   the label is text on top and reads in every language. Hover fades the
   original's lighter state in. Only one green button is ever in view: every
   other button on the site is orange, and everything that opens Discord stays
   blurple.
   -------------------------------------------------------------------------- */
.fight-button {
  --fb-h: 60px;
  --fb-cap: calc(var(--fb-h) * 20 / 86);
  position: relative;
  display: inline-grid;
  min-height: var(--fb-h);
  padding: 6px calc(var(--fb-cap) + 14px) 7px;
  place-items: center;
  isolation: isolate;
  border: 0;
  background: none;
  color: #e9ff83;
  cursor: pointer;
  font-family: "Tanki Quadrat", "Prime Intl", Arial, sans-serif;
  font-size: 20px;
  font-weight: 400;
  letter-spacing: 0.02em;
  line-height: 1.1;
  text-align: center;
  text-shadow: 0 0 7px rgba(214, 255, 110, 0.5), 0 1px 1px rgba(30, 70, 0, 0.45);
  text-transform: uppercase;
  text-wrap: balance;
  transition: transform 90ms ease;
}

.fight-button::before,
.fight-button::after {
  position: absolute;
  inset: 0;
  z-index: -1;
  content: "";
  border-style: solid;
  border-width: 0 var(--fb-cap);
  border-image: url("/assets/fight-button-v1.webp") 0 20 fill / 0 var(--fb-cap) / 0 round stretch;
  pointer-events: none;
}

.fight-button::after {
  border-image-source: url("/assets/fight-button-hover-v1.webp");
  opacity: 0;
  transition: opacity 160ms ease;
}

@media (hover: hover) and (pointer: fine) {
  .fight-button:hover::after {
    opacity: 1;
  }
}

.fight-button:active {
  transform: translateY(1px);
}

.fight-button:focus-visible {
  outline-color: #e9ff83;
}

.fight-button:disabled {
  cursor: default;
  opacity: 0.6;
  transform: none;
}

/* In the hero. */
.fight-button--hero {
  --fb-h: 64px;
  font-size: 23px;
}

/* A form's submit: the full width of its card. */
.fight-button--block {
  --fb-h: 58px;
  display: grid;
  width: 100%;
  margin-top: var(--s-2);
}

/* In the header bar. */
.fight-button--compact {
  --fb-h: 40px;
  font-size: 15px;
}

/* The field only a robot fills in. Off screen rather than display:none, because some
   robots skip anything that is not rendered. */
.c-honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* The orange launcher button: the second action on a page, never the first. */
.c-button {
  position: relative;
  display: inline-flex;
  min-height: 58px;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 0 28px;
  border: 1.5px solid var(--c-orange);
  border-radius: var(--r-control);
  background: linear-gradient(180deg, #232c3a 0%, #121923 55%, #0b1017 100%);
  color: var(--c-orange-hi);
  cursor: pointer;
  font-family: inherit;
  font-size: 1.02rem;
  font-weight: 800;
  line-height: 1.2;
  transition: border-color 180ms ease, color 180ms ease, transform 180ms var(--ease-expo);
}

/* The glow is a pseudo-element's opacity, so no shadow is ever animated. */
.c-button::before {
  position: absolute;
  inset: -1.5px;
  z-index: -1;
  content: "";
  border-radius: inherit;
  box-shadow: var(--glow-orange);
  opacity: 0.7;
  transition: opacity 180ms ease;
}

/* The arrow is drawn, not typed: no font has to carry the glyph. */
.c-button::after {
  width: 7px;
  height: 7px;
  content: "";
  transform: rotate(45deg);
  border-top: 2px solid currentColor;
  border-right: 2px solid currentColor;
  transition: transform 180ms var(--ease-expo);
}

.c-button:hover {
  border-color: #ffb144;
  color: #ffffff;
  transform: translateY(-2px);
}

.c-button:hover::before {
  opacity: 1;
}

.c-button:hover::after {
  transform: rotate(45deg) translate3d(3px, -3px, 0);
}

.c-button:active {
  transform: none;
}

.c-button:disabled {
  cursor: default;
  opacity: 0.6;
  transform: none;
}

.c-button--block {
  display: flex;
  width: 100%;
}

/* The quiet third option: a word with an edge around it. */
.c-button-quiet {
  display: inline-flex;
  min-height: 48px;
  align-items: center;
  justify-content: center;
  padding: 0 20px;
  border: 1px solid var(--c-edge);
  border-radius: var(--r-control);
  background: none;
  color: var(--c-body);
  cursor: pointer;
  font-family: inherit;
  font-size: 0.98rem;
  font-weight: 700;
  transition: border-color var(--t-fast) ease, color var(--t-fast) ease, background-color var(--t-fast) ease;
}

.c-button-quiet:hover {
  border-color: var(--c-edge-strong);
  background-color: rgba(255, 255, 255, 0.04);
  color: var(--c-text);
}

/* Discord's own button: blurple and the white logo at rest and on hover, never
   orange, so it reads as Discord before it is read at all. */
.discord-button {
  display: inline-flex;
  min-height: 56px;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 0 26px;
  border: 0;
  border-radius: var(--r-control);
  background-color: var(--c-discord);
  box-shadow: 0 10px 24px rgba(88, 101, 242, 0.3), inset 0 1px rgba(255, 255, 255, 0.16);
  color: #ffffff;
  cursor: pointer;
  font-family: inherit;
  font-size: 1.05rem;
  font-weight: 800;
  line-height: 1.2;
  transition: background-color var(--t-fast) ease, box-shadow var(--t-fast) ease, transform 110ms ease;
}

.discord-button::before {
  width: 24px;
  height: 24px;
  flex: none;
  content: "";
  background-color: currentColor;
  -webkit-mask: url("/assets/nav-discord.svg") no-repeat center / contain;
  mask: url("/assets/nav-discord.svg") no-repeat center / contain;
}

.discord-button:hover {
  background-color: var(--c-discord-deep);
  box-shadow: 0 12px 28px rgba(88, 101, 242, 0.4), inset 0 1px rgba(255, 255, 255, 0.12);
  color: #ffffff;
  transform: translateY(-1px);
}

.discord-button:active {
  background-color: var(--c-discord-press);
  transform: none;
}

.discord-button:focus-visible {
  outline-color: var(--c-discord-light);
}

.discord-button--small {
  min-height: 46px;
  padding: 0 20px;
  font-size: 0.98rem;
}

.discord-button--block {
  display: flex;
  width: 100%;
}

/* --------------------------------------------------------------------------
   20. The footer. The brand on one side, the way out on the other, and one
   hairline above the fine print, as on the main site. No second row of social
   icons: a creator's own channels belong on the board.
   -------------------------------------------------------------------------- */
.c-footer {
  margin-top: -140px;
  padding: 204px 0 28px;
  background:
    radial-gradient(circle at 17% 24%, rgba(232, 119, 33, 0.055), transparent 25rem),
    radial-gradient(circle at 82% 30%, rgba(78, 139, 186, 0.07), transparent 28rem),
    linear-gradient(180deg, transparent 0, rgba(3, 9, 15, 0.22) 24%, rgba(3, 8, 14, 0.7) 58%, rgba(3, 8, 14, 0.94) 100%);
  /* the glows would otherwise start on a hard edge under the last section */
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 140px);
  mask-image: linear-gradient(180deg, transparent 0, #000 140px);
}

.c-footer .c-shell {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4) var(--s-6);
}

.c-footer .c-shell > a:first-child {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  margin-inline-end: auto;
}

.c-footer img {
  width: 64px;
  height: 64px;
  object-fit: contain;
}

.c-footer b {
  color: var(--c-text);
  font-size: 1.55rem;
  font-weight: 900;
  letter-spacing: -0.035em;
  line-height: 1;
  text-transform: uppercase;
}

/* The way back to the main site. */
.c-footer .c-shell > a:not(:first-child):not(.discord-button) {
  color: var(--c-orange-hi);
  font-size: 0.98rem;
  font-weight: 700;
  transition: color var(--t-fast) ease;
}

.c-footer .c-shell > a:not(:first-child):not(.discord-button):hover {
  color: #ffffff;
}

.c-footer-bottom {
  display: flex;
  flex: 1 0 100%;
  justify-content: space-between;
  gap: 20px;
  margin-top: var(--s-2);
  padding-top: var(--s-4);
  border-top: 1px solid var(--c-edge);
  /* The quietest text on the site, but still text: --c-fine reads at 6.0:1 on
     the foot of the page, where the faded grey this used to be managed 2.7:1
     and failed 1.4.3 outright. Quiet is set by size and weight, not by making
     the line hard to read. */
  color: var(--c-fine);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.085em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   21. Responsive. 980 is the tablet break (the sticky header and sheet are in
   section 7), 700 the phone, 480 the small phone. One HTML for every device.
   -------------------------------------------------------------------------- */
@media (max-width: 980px) {
  /* Two across, not three. .c-rewards is a flex row, so the width comes from
     the card's own basis: a grid-template-columns here would be read by nobody
     and a tablet would keep three cramped cards. */
  .c-rewards > .c-reward {
    flex-basis: calc((100% - var(--s-4)) / 2);
  }

  .c-route {
    gap: var(--s-6) var(--s-7);
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* The chevron belongs between two steps on one line, not across a wrap. */
  .c-route-step:nth-child(odd)::before {
    content: none;
  }

  .c-champion {
    gap: var(--s-2) var(--s-5);
  }

  .c-champion-face {
    width: 120px;
    height: 120px;
    font-size: 3rem;
  }

  .c-hero-copy h1 {
    max-width: none;
  }
}

@media (max-width: 700px) {
  .c-points {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 700px) {
  :root {
    --gutter: max(18px, env(safe-area-inset-left), env(safe-area-inset-right));
    --shell: calc(100% - 2 * var(--gutter));
  }

  /* Long words in German, Armenian and Georgian must break rather than push the
     page sideways. */
  h1,
  h2,
  h3,
  p {
    overflow-wrap: anywhere;
  }

  h1.t-display {
    --fs: clamp(2.75rem, 13vw, 3.75rem);
  }

  h2.t-display {
    --fs: clamp(2rem, 9vw, 2.6rem);
  }

  .c-body {
    font-size: 1rem;
  }

  .c-hero {
    min-height: calc(100svh - var(--header-h));
    padding-block: var(--s-7) var(--s-8);
  }

  /* The words cover more of a phone screen and the footage under them is at its
     busiest, so the pool of shade widens and the page fade starts higher. Still
     three static gradients: nothing here is blurred or animated. */
  .c-hero-shade {
    background:
      radial-gradient(ellipse 82% 40% at 50% 46%, rgba(3, 8, 14, 0.74), rgba(3, 8, 14, 0.5) 62%, rgba(3, 8, 14, 0.26)),
      linear-gradient(180deg, rgba(2, 6, 10, 0.6) 0%, rgba(2, 6, 10, 0.3) 24%, rgba(3, 8, 14, 0.44) 62%, rgba(5, 13, 22, 0.78) 100%);
  }

  .c-hero-copy .c-lead {
    max-width: 34ch;
  }

  .c-hero-actions {
    flex-direction: column;
    align-items: stretch;
  }

  .c-hero-actions .fight-button,
  .c-hero-actions .c-button {
    width: 100%;
  }

  .fight-button--hero {
    --fb-h: 56px;
    font-size: 16px;
  }

  .fight-button--block {
    --fb-h: 54px;
    font-size: 16px;
  }

  /* The pinned apply control has nowhere to sit next to the menu and the flag
     at this width: every page carries its own apply button anyway. */
  .c-header-apply {
    display: none;
  }

  .c-stats {
    margin-top: -32px;
    gap: 20px;
    grid-template-columns: minmax(0, 1fr);
  }

  .c-tier {
    flex-basis: 100%;
    min-width: 0;
  }

  /* One column, with the icon beside the words instead of above them. The card
     gives up its 260px floor as well: below it a basis of 100% would still be
     stretched wider than the screen. */
  .c-rewards > .c-reward {
    flex-basis: 100%;
    min-width: 0;
  }

  /* Only a reward that has a picture becomes two columns: one without art
     would otherwise drop its words into the empty icon column. */
  .c-reward:has(.c-reward-art) {
    gap: var(--s-1) var(--s-4);
    grid-template-columns: auto minmax(0, 1fr);
  }

  .c-reward {
    justify-items: start;
    text-align: left;
  }

  .c-reward-art {
    min-height: 0;
    grid-row: span 4;
    align-self: center;
  }

  .c-reward-art img {
    height: 64px;
  }

  .c-route {
    gap: 28px;
    grid-template-columns: minmax(0, 1fr);
  }

  /* Stacked, the chevrons would point across a line break. The list keeps the
     order for a screen reader. */
  .c-route-step::before {
    content: none;
  }

  .c-form-stage {
    padding: 26px 20px;
  }

  .c-field-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .c-champion {
    min-height: 0;
    gap: var(--s-3);
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "face"
      "name"
      "links"
      "metric"
      "lead";
    justify-items: center;
    text-align: center;
  }

  .c-champion-art {
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 60%);
    mask-image: linear-gradient(180deg, transparent, #000 60%);
  }

  /* The board never scrolls sideways: the movement drops under the metric. */
  .c-row {
    padding: 10px var(--s-3);
    gap: 4px var(--s-2);
    grid-template-columns: 2.25rem 40px minmax(0, 1fr) auto;
    grid-template-areas:
      "pos face name   metric"
      "pos face links  move"
      "pos face gap    gap";
    contain-intrinsic-size: auto 72px;
  }

  .c-face {
    width: 40px;
    height: 40px;
  }

  .c-face--letter {
    font-size: 1.1rem;
  }

  .c-row.is-second .c-row-name {
    font-size: 1.1rem;
  }

  .c-row.is-third .c-row-name {
    font-size: 1.02rem;
  }

  .c-row.is-second .c-row-pos {
    width: 32px;
    height: 32px;
    font-size: 1.35rem;
  }

  .c-row.is-third .c-row-pos {
    width: 30px;
    height: 30px;
    font-size: 1.25rem;
  }

  /* The hall of fame becomes a swipe strip with a peek of the next card. */
  .c-hof {
    display: grid;
    width: 100vw;
    margin-inline: calc(50% - 50vw);
    padding: 0 var(--gutter) var(--s-2);
    gap: var(--s-3);
    grid-auto-columns: min(62vw, 220px);
    grid-auto-flow: column;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-padding-inline: var(--gutter);
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }

  .c-hof::-webkit-scrollbar {
    display: none;
  }

  .c-hof-card {
    width: auto;
    scroll-snap-align: start;
  }

  .c-footer .c-shell {
    flex-direction: column;
    align-items: flex-start;
  }

  .c-footer .c-shell > a:first-child {
    margin-inline-end: 0;
  }

  .c-footer-bottom {
    flex-direction: column;
    gap: 5px;
  }
}

/* Phone form rules must stay after the base form rules above: 16px text is what
   stops iOS zooming into a field, and 48px is the smallest comfortable target. */
@media (max-width: 700px) {
  .c-form input,
  .c-form select,
  .c-form textarea {
    min-height: 48px;
    font-size: 16px;
  }

  .c-form textarea {
    min-height: 120px;
  }

  .c-button,
  .discord-button {
    min-height: 52px;
  }
}

/* Touch devices: the effects a phone GPU pays for, and every hover state, go. */
@media (hover: none) and (pointer: coarse) {
  /* A live blur behind a bar over a scrolling page costs more on a phone than
     it is worth. The bar keeps its colour, it just stops blurring. */
  .c-header::before {
    background: rgba(4, 9, 15, 0.88);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    animation: none;
  }

  .lang-menu {
    background: rgba(8, 14, 22, 0.96);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  .c-tier:hover,
  .c-button:hover,
  .discord-button:hover,
  .c-row-links a:hover {
    transform: none;
  }

  .c-tier:hover::before {
    opacity: 0;
  }
}

@media (max-width: 480px) {
  /* On one line the brand pushed the flag off a 320px screen. Stacked, both
     words stay and the bar still holds the menu and the language control. */
  .c-wordmark {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }

  .c-wordmark span {
    font-size: 0.76rem;
    letter-spacing: 0.18em;
  }

  .c-wordmark b {
    font-size: 0.6rem;
    letter-spacing: 0.14em;
  }

  .c-champion-face {
    width: 104px;
    height: 104px;
    font-size: 2.5rem;
  }

  .c-champion-metric {
    --fs: clamp(3rem, 16vw, 4rem);
  }

  .c-milestones {
    gap: var(--s-4) var(--s-3);
  }

  .c-milestone {
    flex-basis: 96px;
  }

  .c-faq-item summary {
    padding: 16px 16px;
    font-size: 1.02rem;
  }

  .c-faq-body {
    padding: 0 16px 18px;
  }

  /* Armenian words run long, and at this width a heading would otherwise break
     mid-word. One step smaller fits them. */
  [lang="hy"] h1.t-display {
    --fs: clamp(2.25rem, 11vw, 2.75rem);
  }
}

/* The human check never goes below 300px wide, which would push a form card
   past the edge of a 320px phone. zoom, unlike scale, also shrinks the space it
   takes. */
@media (max-width: 380px) {
  .c-form-stage {
    padding-inline: var(--s-4);
  }

  .c-form-stage .cf-turnstile {
    zoom: 0.86;
  }

  .c-form input::placeholder {
    font-size: 0.88em;
  }

  .lang-switch {
    min-width: 48px;
  }

  .lang-current .lang-code {
    display: none;
  }

  .c-row {
    grid-template-columns: 2rem 36px minmax(0, 1fr) auto;
  }

  .c-face {
    width: 36px;
    height: 36px;
  }
}

/* --------------------------------------------------------------------------
   22. Lite mode. creator-site.js puts .is-lite on <html> where the machine
   reports four cores or 4 GB or less, or a data saver. Those machines keep the
   pictures, the footage and every word: they lose the drifting layers, the
   shine and the running ticker. The gates are on the animations themselves
   (html:not(.is-lite)), so nothing here has to be switched off with a kill
   rule.
   -------------------------------------------------------------------------- */
html.is-lite .c-header::before {
  background: rgba(4, 9, 15, 0.84);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  animation: none;
}

html.is-lite .c-grain {
  display: none;
}

/* --------------------------------------------------------------------------
   23. Reduced motion. Nothing that moves is left: what remains is colour. The
   keyframes above are already inside prefers-reduced-motion: no-preference, so
   this block only has to settle the hover transforms, and it does it by
   overriding them rather than with !important.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .c-tier,
  .c-button,
  .c-button::after,
  .discord-button,
  .c-row-links a,
  .c-header-apply,
  .lang-pill {
    transition: none;
  }

  .c-tier:hover,
  .c-tier:focus-within,
  .c-button:hover,
  .discord-button:hover,
  .c-row-links a:hover {
    transform: none;
  }

  .c-button:hover::after {
    transform: rotate(45deg);
  }

  .c-header-apply.is-in {
    transform: none;
  }

  .c-faq-caret {
    transition: none;
  }
}

/* --------------------------------------------------------------------------
   24. The display face per language. Anton carries no Cyrillic, Georgian or
   Armenian at all, so on those pages a heading would fall through to Inter at
   weight 400, which is thin, and a mixed line would pair two different cap
   heights. The whole element switches family instead, one step heavier and
   smaller, because Inter and the Noto faces run 1.45 to 1.65 times Anton's
   width for the same words.

   Numbers are the exception: they are digits and separators, Anton has them
   all, and a count must look the same in every language.

   Portuguese pages declare lang="pt-BR" and German "de"; Anton covers Latin-1,
   so neither needs a switch. The language CODE is ka and hy: the folders ge and
   am are country names, and lang="ge" or lang="am" would be wrong.
   -------------------------------------------------------------------------- */
:is(:lang(ru), :lang(ka), :lang(hy)) .t-display:not(.c-stat-num, .c-champion-metric, .c-reward-value) {
  font-family: "Prime Text", "Prime Intl", Arial, sans-serif;
  font-size: calc(var(--fs, 2rem) * 0.72);
  font-weight: 900;
  letter-spacing: -0.02em;
  line-height: 1.02;
  text-wrap: balance;
}

/* Georgian has no capitals: uppercase gives Mtavruli, which is correct for a
   heading, but the tracking that suits English capitals is too wide for it.
   Armenian capitals are wide as well. */
:is(:lang(ka), :lang(hy)) .t-display:not(.c-stat-num, .c-champion-metric, .c-reward-value) {
  font-weight: 800;
  letter-spacing: 0;
}

/* The medals keep the game's numerals whatever the page's language. */
:is(:lang(ru), :lang(ka), :lang(hy)) .c-row.is-second .c-row-pos,
:is(:lang(ru), :lang(ka), :lang(hy)) .c-row.is-third .c-row-pos {
  font-family: "Prime Display", "Prime Intl", Impact, sans-serif;
  font-weight: 400;
}
