/* ============================================================
   05 - SUPPORTED GAMES (cycling marquee)

   The owner asked for this one by name: cycle through the games the way
   swills.gg does, and drop every per-game FPS figure. So the section is now one
   small label line and one slow, seamless strip of game art. No numbers, no
   caveats, no per-game copy: the art names the title and nothing claims a
   result.

   HOW THE LOOP IS SEAMLESS
   Every tile is the same width and carries its gap as margin-right (NOT flex
   `gap`), so one set of five measures exactly 5 * (tile + gap) with no odd gap
   at the join. The track holds three identical sets and slides left by exactly
   one set width, at which point set 2 sits pixel-for-pixel where set 1 started
   and the animation restarts with nothing to see. Two sets (1920px at desktop
   sizing) always cover the 1040px column, so empty track can never scroll in.

   WHY IT CANNOT OVERFLOW THE PAGE
   The track is far wider than the screen, but it lives inside .games-marquee,
   which is `overflow: hidden` and sized in % (via .col-mid), never in vw. A vw
   width is the classic full-bleed marquee bug: 100vw includes the scrollbar,
   so it adds ~15px to the document scroll width. Nothing here is sized in vw.

   Motion is one CSS transform animation on one element, so it runs on the
   compositor. There is no JS in this section and no scroll listener, so it
   cannot hijack, throttle, or fight the page scroll.
   ============================================================ */

#games {
  /* Local geometry and one timing token. theme.css owns INTERACTION durations
     (--t-fast/--t/--t-slow, all under half a second); an ambient loop is a
     different animal, so its single duration is named here rather than left as
     a magic number in the keyframe. --games-cycle is the time to travel one
     set, i.e. about 40px per second: slow enough to read, never a distraction. */
  --games-tile-w: 178px;
  --games-tile-h: 92px;
  --games-gap: 14px;
  --games-cycle: 24s;
}

/* ---------- the label row ----------
   Pass 3. This section used to open with the same centred eyebrow, 40px title
   and sub sentence as six others. It now opens with a label: the strip is the
   content and it does not need announcing, only naming.

   Left on the row is the heading (a real h2, sized as a label), right is the
   one fact that is not visible in the art itself. Baseline aligned so the two
   sit on a shared line rather than in two boxes, and wrapping so the note drops
   under the label on a narrow phone instead of squeezing it.

   The gap under it is deliberately tighter than the shared section-head gap: a
   small label belongs close to the thing it labels, where a banner needs air. */
.games-bar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px 20px;
  flex-wrap: wrap;
  margin-bottom: clamp(18px, 2.2vw, 26px);
}
.games-label {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  line-height: 1.35;
  color: var(--text-dim);
}
/* instrument face, the same quiet spec voice the counts and prices use */
.games-note {
  font-family: var(--font-price);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: normal;
  color: var(--text-mute);
}

/* ---------- the viewport ---------- */
.games-marquee {
  position: relative;
  overflow: hidden;              /* this is what keeps the track off the document */
  /* Alpha ramp so the tiles dissolve into the page at both ends instead of
     being guillotined by the column edge. The #000 here is a mask's alpha
     channel, not a palette colour: only its opacity is read. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
}

.games-track {
  display: flex;
  width: max-content;
  will-change: transform;
  animation: gamesMarquee var(--games-cycle) linear infinite;
}
/* Hovering is the one moment someone wants to actually look at a logo. */
.games-marquee:hover .games-track { animation-play-state: paused; }

.games-set { display: flex; list-style: none; }

/* ---------- a tile ----------
   Margin, not gap: see the seam note at the top of the file. */
.games-tile {
  position: relative;
  flex: 0 0 auto;
  width: var(--games-tile-w);
  height: var(--games-tile-h);
  margin-right: var(--games-gap);
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  background: var(--bg-1);
  overflow: hidden;              /* clips the art to the rounded corners */
}
/* ONE rule for all five, deliberately.
   The five source assets are three different kinds of thing: Fortnite and CS2
   are wide key-art banners, Valorant, Roblox and Minecraft are wordmarks. The
   previous version gave each kind its own treatment (cover here, contain and a
   green backdrop there), which is exactly why the row looked uneven even though
   every tile box measured an identical 178x92: the ARTWORK inside was sized
   three different ways.

   So every tile now gets the same surface and every image is contained to the
   same optical box. A contained wide banner still very nearly fills a tile this
   shape, so Fortnite and CS2 lose almost nothing, and the wordmarks stop being
   either tiny or full-bleed. */
/* Full-bleed game art, per the owner: the earlier uniform-contain treatment made
   every tile the same optical size but drained the row of colour, and the varied
   artwork reads better even though the marks inside sit at different scales.
   The tile BOXES stay identical; only what fills them varies. */
.games-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* One veil over every tile so five very different artworks (a cyan Fortnite sky,
   orange CS2 key art, navy Valorant) settle to the same weight on a near-black
   page instead of fighting each other. rgba of --bg-0, the same way .nav-inner
   tints in site.css. */
.games-tile::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(8, 11, 17, .10), rgba(8, 11, 17, .34));
}

/* Minecraft ships a transparent stone-grey wordmark, invisible on ink, so it
   needs a light backdrop. #5C8A34 is Minecraft's own plains grass tint: it is
   game artwork, exactly like the baked-in colours of the other four images, not
   a site palette colour. Padding on the replaced element (border-box) insets the
   wordmark, since object-fit ignores the parent's padding otherwise. */
.games-tile[data-game="minecraft"] { background: #5C8A34; }
.games-tile[data-game="minecraft"] img { object-fit: contain; padding: 16px 18px; }

/* Roblox ships a black wordmark on white, which in a dark row would be a
   floodlight. Inverting flips it to the white-on-ink the brand uses on dark
   backgrounds anyway. The veil is skipped: there is no artwork to settle, only a
   wordmark that has to stay legible. */
.games-tile[data-game="roblox"] img { filter: invert(1); }
.games-tile[data-game="roblox"]::after { display: none; }

@keyframes gamesMarquee {
  from { transform: translate3d(0, 0, 0); }
  /* exactly one set: five tiles, each carrying its own trailing gap */
  to   { transform: translate3d(calc(-5 * (var(--games-tile-w) + var(--games-gap))), 0, 0); }
}

/* ============================================================
   Responsive. Only the three geometry tokens change; the keyframe is written
   in terms of them, so the travel distance and therefore the seam stay exact
   at every size. Speed is held near 40px/s throughout.
   ============================================================ */
@media (max-width: 900px) {
  #games { --games-tile-w: 158px; --games-tile-h: 86px; --games-gap: 12px; --games-cycle: 21s; }
}
@media (max-width: 560px) {
  #games { --games-tile-w: 138px; --games-tile-h: 76px; --games-gap: 10px; --games-cycle: 18s; }
}
@media (max-width: 400px) {
  #games { --games-tile-w: 124px; --games-tile-h: 68px; --games-gap: 9px; --games-cycle: 17s; }
}

/* ============================================================
   Reduced motion: a static row, not a slower one.

   site.css clamps every animation-duration to .001s !important, which for an
   INFINITE loop is a strobe rather than a stop, so the animation has to be
   removed by name (animation-duration cannot win against that !important).
   The two decorative sets are dropped, the remaining five tiles centre and
   wrap, and the edge fade comes off since nothing is entering or leaving.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .games-marquee {
    -webkit-mask-image: none;
            mask-image: none;
  }
  .games-track {
    animation: none;
    transform: none;
    will-change: auto;
    width: 100%;
    flex-wrap: wrap;
    justify-content: center;
  }
  .games-set {
    flex: 1 1 100%;
    flex-wrap: wrap;
    justify-content: center;
    row-gap: var(--games-gap);
  }
  .games-set + .games-set { display: none; }
  /* split the gap either side so the static row centres evenly */
  .games-tile { margin: 0 calc(var(--games-gap) / 2); }
}
