/* ============================================================================
   GAMESWA — BASE LAYER
   Session A scaffold · 2026-08-10
   Loads AFTER style.css. Layout primitives, typography, the quality floor.
   Everything here is either a `.gw-` class or a deliberate, listed global.
   ========================================================================== */

/* ── DELIBERATE GLOBALS ──────────────────────────────────────────────────
   Three, and only three. Each is one line and trivially revertible.        */

/* G1 · Body face DM Sans -> Barlow. Brand tokens are law and Barlow is the
   brand body face. Display type was already Barlow Condensed, so this is the
   last piece. Revert = delete this rule. */
body { font-family: var(--gw-font-body); }

/* G2 · Box sizing. The old sheet never set it; new components assume it. */
*, *::before, *::after { box-sizing: border-box; }

/* G3 · Visible keyboard focus everywhere. The old sheet had none, which is a
   quality-floor failure on every page, not just new ones. Mouse users are
   unaffected (:focus-visible). */
:focus-visible {
  outline: 2px solid var(--gw-accent);
  outline-offset: 3px;
  border-radius: var(--gw-r-xs);
}
html.gw-dark :focus-visible,
.gw-invert :focus-visible { outline-color: var(--gw-punct); }

/* ── [hidden] MUST WIN ───────────────────────────────────────────────────
   Session F, 2026-08-11. THIS IS LOAD-BEARING. Do not delete it.

   `[hidden] { display: none }` lives in the user-agent sheet, so ANY author
   rule that sets `display` on the same element beats it and `hidden` silently
   stops working. The element stays on the page, taking space and often taking
   taps, while the markup and the JavaScript both believe it is gone.

   This has now bitten this codebase four separate times:
     1. .gw-nav__menu   display:flex  — the closed mobile menu covered the
        whole viewport and ate every tap below 900px. Found by B and C.
     2. .gw-loop__cap   patched locally in home.css by B.
     3. .ucc-headline   display:grid  — /unity-cup ships the headline stat
        `hidden` with a literal 0 in the markup, to be replaced once the
        verified data arrives. Because `hidden` did nothing, the page rendered
        "0%" to anyone on a slow connection until the JSON landed. That is an
        unverified number on screen, which is the one thing this site does not
        do. Found by this session at 200ms latency.
     4. Any future one, because the trap is invisible in review.

   Three local patches for one systemic defect is two too many. This is the
   general fix. `!important` is deliberate and is the standard treatment: a
   reset for an attribute whose entire contract is "this element is not
   rendered" has to outrank component styling, or the contract is a lie.

   If you genuinely need a hidden element to render, do not weaken this rule.
   Remove the attribute. That is what it means. */
[hidden] { display: none !important; }

/* ── SCAFFOLD ROOT ───────────────────────────────────────────────────────
   New pages put `class="gw"` on <body>. Existing index.html does not, so the
   home page is untouched until Session B opts it in. */
body.gw {
  background: var(--gw-surface);
  color: var(--gw-text);
  font-family: var(--gw-font-body);
  font-size: var(--gw-t-body);
  line-height: var(--gw-leading-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  /* Mobile sticky CTA bar clearance. Desktop: bar is hidden, padding is 0. */
  padding-bottom: var(--gw-cta-bar-h);
}
@media (min-width: 768px) { body.gw { padding-bottom: 0; } }

/* Theme changes must not animate the whole page on toggle. */
body.gw, .gw-section { transition: background-color var(--gw-dur-base) ease, color var(--gw-dur-base) ease; }

/* ── LAYOUT ──────────────────────────────────────────────────────────────
   Mobile-first: 390px is the design width, desktop is the adaptation. */
.gw-wrap {
  max-width: var(--gw-wrap);
  margin-inline: auto;
  padding-inline: var(--gw-gutter);
}
.gw-section {
  padding-block: var(--gw-section-y);
  background: var(--gw-surface);
  color: var(--gw-text);
}
.gw-section--alt { background: var(--gw-surface-3); }
.gw-section--rule { border-top: 1px solid var(--gw-rule); }

/* The nav is fixed, so the first section of a page has to clear it. The one
   exception is a full-bleed hero the nav is meant to float over — that hero
   just does not take this class. */
.gw-section--first { padding-top: calc(60px + var(--gw-section-y)); }
/* Anchor links must not land under the fixed nav either. */
html { scroll-padding-top: 76px; }

.gw-stack > * + * { margin-top: var(--gw-s-4); }
.gw-stack-lg > * + * { margin-top: var(--gw-s-6); }

/* One column on mobile, always. Two only when there is room for two. */
.gw-grid-2 { display: grid; grid-template-columns: 1fr; gap: var(--gw-s-6); }
.gw-grid-3 { display: grid; grid-template-columns: 1fr; gap: var(--gw-s-5); }
@media (min-width: 768px) {
  .gw-grid-2 { grid-template-columns: 1fr 1fr; gap: var(--gw-s-8); }
  .gw-grid-3 { grid-template-columns: repeat(3, 1fr); }
}

/* ── TYPE ────────────────────────────────────────────────────────────────
   Display is condensed, heavy, uppercase, tight. Body is Barlow, generous. */
.gw-display {
  font-family: var(--gw-font-display);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: var(--gw-track-display);
  line-height: var(--gw-leading-display);
  margin: 0;
  color: var(--gw-text);
  text-wrap: balance;
}
.gw-display--hero { font-size: var(--gw-t-hero); }
.gw-display--xxl  { font-size: var(--gw-t-xxl); }
.gw-display--xl   { font-size: var(--gw-t-xl); }
.gw-display--lg   { font-size: var(--gw-t-lg); }
.gw-display--sm   { font-size: var(--gw-t-md); font-weight: 700; letter-spacing: 0.01em; }

.gw-body     { font-size: var(--gw-t-body); line-height: var(--gw-leading-body); color: var(--gw-text-muted); max-width: 62ch; }
.gw-body--lead { font-size: var(--gw-t-md); color: var(--gw-text); }
.gw-body--sm { font-size: var(--gw-t-sm); }

.gw-accent { color: var(--gw-accent-text); }
.gw-punct  { color: var(--gw-punct); }

/* Data voice: timestamps, over markers, section eyebrows, stat units.
   Tabular figures so numbers never jitter while counting up. */
.gw-data {
  font-family: var(--gw-font-data);
  font-size: var(--gw-t-data);
  letter-spacing: var(--gw-track-data);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--gw-text-faint);
}

/* ── LINKS ───────────────────────────────────────────────────────────────
   SPECIFICITY, and this :where() is load-bearing. Read before changing it.

   This is a RESET, not a rule: it exists so a bare <a> does not come out
   UA-blue and underlined. It must therefore sit BELOW every component that
   states its own colour.

   Written plainly as `.gw a` it is (0,1,1), which outranks `.gw-btn--primary`,
   `.gw-skip` and `.gw-link` at (0,1,0). Those all then silently inherited the
   surrounding text colour instead of their own token, which put ink type on
   the blue CTA (2.90:1) and white type on the WhatsApp CTA (1.98:1). Both
   fail WCAG AA. Found by computing the pairs on /players, 2026-08-11.

   `:where()` contributes zero, so this drops to (0,1,0) and every component
   colour declared later in the cascade wins, which is the whole intent. It
   still beats the UA sheet, because author styles always do.

   Note this is the OPPOSITE case to the light-theme overrides in tokens.css,
   where :where() would be a bug. There we need to WIN. Here we need to lose. */
.gw :where(a) { color: inherit; text-decoration: none; }

/* Session F, 2026-08-11: C and E independently found the same root cause and
   fixed it from opposite ends. C lowered the reset above to (0,1,0) with
   :where(), which repairs every component at once: buttons, skip link and
   .gw-link. E raised this one component to (0,2,0). Both are kept and they
   compose, because the reset no longer outranks anything and this rule is
   belt-and-braces on top of that. E's symptom report, kept because it is the
   one that documents what it looked like: the reset beat `.gw-link` and EVERY
   .gw-link on the site rendered as plain muted body text with no underline.
   Found on /about on 2026-08-11 by reading computed styles, not by looking at
   it: a grey unstyled link looks like a design choice until you try to click
   it. Do not flatten either half back. */
.gw .gw-link {
  color: var(--gw-accent-text);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
.gw .gw-link:hover { text-decoration-thickness: 2px; }

/* ── MEDIA · ZERO LAYOUT SHIFT ───────────────────────────────────────────
   Every media slot reserves its box before the asset arrives. No exceptions:
   a shifting page on turf data is the thing we are trying not to be. */
.gw img, .gw video { max-width: 100%; height: auto; display: block; }

/* ── REVEAL ──────────────────────────────────────────────────────────────
   transform/opacity only. Instant under reduced motion (durations collapse)
   and .gw-reveal is unhidden immediately if JS never runs (see .no-js). */
.gw-reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--gw-dur-slow) var(--gw-ease), transform var(--gw-dur-slow) var(--gw-ease);
  will-change: opacity, transform;
}
.gw-reveal.is-visible { opacity: 1; transform: none; }
.gw-reveal--d1 { transition-delay: 0.07s; }
.gw-reveal--d2 { transition-delay: 0.14s; }
.gw-reveal--d3 { transition-delay: 0.21s; }
@media (prefers-reduced-motion: reduce) {
  .gw-reveal { opacity: 1; transform: none; transition: none; }
}
/* No JS, no IntersectionObserver, no hidden content. */
html.no-js .gw-reveal { opacity: 1; transform: none; }

/* ── UTILITIES ───────────────────────────────────────────────────────────*/
.gw-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
/* Skip link — first tabbable element on every page. */
.gw-skip {
  position: absolute; left: var(--gw-s-4); top: -100%;
  z-index: var(--gw-z-overlay);
  padding: var(--gw-s-3) var(--gw-s-4);
  background: var(--gw-accent); color: var(--gw-on-accent);
  font-family: var(--gw-font-display); font-weight: 800; text-transform: uppercase;
  border-radius: var(--gw-r-sm);
}
.gw-skip:focus { top: var(--gw-s-4); }

.gw-hide-mobile { display: none; }
@media (min-width: 768px) {
  .gw-hide-mobile { display: revert; }
  .gw-hide-desktop { display: none; }
}
