/* ============================================================================
   GAMESWA — SHARED COMPONENTS
   Session A scaffold · 2026-08-10
   ----------------------------------------------------------------------------
   Broadcast vernacular: the design language of cricket broadcast graphics is
   our subject's own world and our product's own output. Status chips are
   broadcast bugs. Timestamps are a motif. Nothing here is decorative for its
   own sake.

   Page sessions COMPOSE these. If you need a variant, add a modifier here so
   every page gets it. Do not fork a component into a page.
   ========================================================================== */

/* ── STATUS CHIP · BROADCAST BUG ─────────────────────────────────────────
   Two status chips exist. LIVE and IN BUILD. There is no third status chip,
   and neither is ever used to describe something we have not actually
   shipped.

   <span class="gw-chip gw-chip--live">Live</span>
   <span class="gw-chip gw-chip--build">In build</span>

   RED IS NOT A STATUS COLOUR. Session F, 2026-08-11, decided change.

   The LIVE status chip used to be signal red with a pulsing dot. That is the
   visual language broadcast uses for "this picture is happening right now",
   and we were spending it on a different claim: "this capability is shipped".
   A page carrying a pulsing red bug next to a shipped feature reads as a
   match in progress, and when we do put a real stream on the site there is
   no stronger signal left to reach for.

   So LIVE is now a lime fill with ink type, positive and confident, and it
   is a status chip like any other. Signal red and the pulse move to
   .gw-chip--onair, which means one thing only: a camera is live right now.
   Nothing on the site carries --onair today, and nothing should until a real
   stream is on the page.                                                    */

.gw-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--gw-s-2);
  padding: 5px 10px;
  border-radius: var(--gw-r-xs);
  font-family: var(--gw-font-data);
  font-size: var(--gw-t-data);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
  border: 1px solid transparent;
}

/* LIVE — shipped and running. Lime FILL with ink type, so it reads as a
   confident positive rather than an alarm. --gw-punct-fill stays the real
   brand lime in both themes and --gw-on-punct is ink on it at 13.3:1, which
   is why this pair is safe in light theme where lime as TYPE would not be.
   No pulse: nothing is happening right now, something is simply true. */
.gw-chip--live {
  background: var(--gw-punct-fill);
  border-color: var(--gw-punct-fill);
  color: var(--gw-on-punct);
}
.gw-chip--live::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--gw-on-punct);
}

/* ON AIR — a camera is live RIGHT NOW. This is the only thing on the site
   allowed to use signal red, and the only thing allowed to pulse. Do not
   reach for it to mean "shipped", "new", "important" or "urgent": the whole
   value of this chip is that it is almost never on screen.

   <span class="gw-chip gw-chip--onair">On air</span>                       */
.gw-chip--onair {
  background: rgba(229, 52, 42, 0.10);
  border-color: rgba(229, 52, 42, 0.35);
  color: var(--gw-signal);
}
.gw-chip--onair::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--gw-signal);
  box-shadow: 0 0 0 0 rgba(229, 52, 42, 0.5);
  animation: gw-bug-pulse 2s ease-out infinite;
}
@keyframes gw-bug-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(229, 52, 42, 0.5); }
  70%  { box-shadow: 0 0 0 7px rgba(229, 52, 42, 0); }
  100% { box-shadow: 0 0 0 0 rgba(229, 52, 42, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .gw-chip--onair::before { animation: none; }
}

/* IN BUILD — slate tag. Deliberately quiet: it is a promise, not a claim. */
.gw-chip--build {
  background: var(--gw-surface-3);
  border-color: var(--gw-rule-strong);
  color: var(--gw-text-muted);
}
.gw-chip--build::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 1px;
  background: var(--gw-text-faint);
}

/* ── EYEBROW · TIMESTAMP MOTIF ───────────────────────────────────────────
   The scorer timestamp is the moat, so it is also the typographic signature.
   Use on genuinely sequential content only (funnel steps, clip cards, ordered
   sections). Do not put a fake over-number on an unordered block.

   <p class="gw-eyebrow"><span class="gw-eyebrow__mark">OVER 14.3</span> What we do</p> */

.gw-eyebrow {
  display: flex;
  align-items: center;
  gap: var(--gw-s-3);
  margin: 0 0 var(--gw-s-4);
  /* Stated, not inherited: an eyebrow is also a legitimate <h2> when a section
     has no display headline, and a heading would otherwise synthesise a bold
     weight DM Mono does not ship. Session E, /about. */
  font-weight: 400;
  font-family: var(--gw-font-data);
  font-size: var(--gw-t-data);
  letter-spacing: var(--gw-track-data);
  text-transform: uppercase;
  color: var(--gw-accent-text);
}
.gw-eyebrow__mark {
  padding: 3px 7px;
  border: 1px solid var(--gw-rule-strong);
  border-radius: var(--gw-r-xs);
  color: var(--gw-text-faint);
  font-variant-numeric: tabular-nums;
}
.gw-eyebrow::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--gw-rule);
}

/* ── BUTTONS ─────────────────────────────────────────────────────────────
   One accent CTA per view. Minimum 44px tap target, always.               */

.gw-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--gw-s-2);
  min-height: 44px;
  padding: var(--gw-s-3) var(--gw-s-5);
  border: 1px solid transparent;
  border-radius: var(--gw-r-sm);
  font-family: var(--gw-font-display);
  font-weight: 800;
  font-size: 0.9375rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: transform var(--gw-dur-fast) var(--gw-ease),
              box-shadow var(--gw-dur-fast) var(--gw-ease),
              background-color var(--gw-dur-fast) ease;
}
.gw-btn:hover  { transform: translateY(-1px); }
.gw-btn:active { transform: translateY(0); }

.gw-btn--wa {
  background: var(--gw-wa);
  color: var(--gw-on-wa);   /* ink. 9.86:1. White was 1.98:1 and failed AA. */
  box-shadow: 0 3px 14px rgba(37, 211, 102, 0.25);
}
.gw-btn--wa:hover { box-shadow: 0 6px 20px rgba(37, 211, 102, 0.32); }

.gw-btn--primary {
  background: var(--gw-accent);
  color: var(--gw-on-accent);
}
.gw-btn--punct {
  background: var(--gw-punct-fill);
  color: var(--gw-on-punct);
}
.gw-btn--ghost {
  background: transparent;
  color: var(--gw-text);
  border-color: var(--gw-rule-strong);
}
.gw-btn--ghost:hover { background: var(--gw-surface-3); }
.gw-btn--block { width: 100%; }

/* F5 · a disabled action must SAY WHY. The reason is not optional chrome;
   it is the whole point. Markup:
     <button class="gw-btn" disabled aria-describedby="why-x">Send</button>
     <p id="why-x" class="gw-btn-reason">Add a ground name first.</p>          */
.gw-btn:disabled,
.gw-btn[aria-disabled='true'] {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}
.gw-btn-reason {
  margin: var(--gw-s-2) 0 0;
  font-family: var(--gw-font-data);
  font-size: var(--gw-t-data);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gw-text-faint);
}

/* ── STICKY MOBILE CTA BAR ───────────────────────────────────────────────
   Every page, always in thumb reach, one accent CTA, no competing buttons.
   Desktop hides it (the nav CTA takes over).                              */

.gw-cta-bar {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: var(--gw-z-sticky);
  display: flex;
  align-items: center;
  gap: var(--gw-s-3);
  padding: var(--gw-s-2) var(--gw-s-4);
  padding-bottom: calc(var(--gw-s-2) + env(safe-area-inset-bottom, 0px));
  background: var(--gw-scrim);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-top: 1px solid var(--gw-rule);
}
.gw-cta-bar__label {
  flex: 1;
  min-width: 0;
  font-family: var(--gw-font-data);
  font-size: var(--gw-t-data);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gw-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The label is per-page copy now (see the CTA variants in check-chrome.sh),
   so it is not always twenty characters. "Talk to us about your venue" is
   twenty-seven, and at 390px the ellipsis was eating the last word, which
   turns a CTA into a riddle. Tightening the tracking on narrow screens buys
   the room without shrinking the type or wrapping the bar to two lines.
   The ellipsis stays as the backstop for anything longer still.
   Session G · 2026-08-11 */
@media (max-width: 430px) {
  .gw-cta-bar { gap: var(--gw-s-2); }
  .gw-cta-bar__label { letter-spacing: 0.04em; }
}
/* 360px is the site's floor and the longest label still did not fit there on
   tracking alone. The bar's own side padding gives up 4px a side, which the
   button never notices and the label does. */
@media (max-width: 375px) {
  .gw-cta-bar { padding-inline: var(--gw-s-3); }
  .gw-cta-bar__label { letter-spacing: 0.03em; }
}

@media (min-width: 768px) { .gw-cta-bar { display: none; } }

/* ── CARD ────────────────────────────────────────────────────────────────*/
.gw-card {
  background: var(--gw-surface-2);
  border: 1px solid var(--gw-rule);
  border-radius: var(--gw-r-md);
  padding: var(--gw-s-5);
}
.gw-card__title {
  font-family: var(--gw-font-display);
  font-weight: 800;
  font-size: var(--gw-t-md);
  text-transform: uppercase;
  letter-spacing: 0.01em;
  line-height: 1.1;
  margin: 0 0 var(--gw-s-2);
  color: var(--gw-text);
}

/* ── MEDIA SLOT ──────────────────────────────────────────────────────────
   Three states, one box, zero layout shift. The box is reserved by
   aspect-ratio BEFORE anything loads. See assets/js/media.js and
   media/manifest.json — dropping a file in requires no code change.

   <figure class="gw-media" data-slot="M1" style="--gw-media-ar:16/9"></figure> */

.gw-media {
  position: relative;
  margin: 0;
  aspect-ratio: var(--gw-media-ar, 16 / 9);
  overflow: hidden;
  border-radius: var(--gw-r-md);
  background: var(--gw-surface-3);
  border: 1px solid var(--gw-rule);
}
.gw-media > video,
.gw-media > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* State 3 · designed placeholder. Never a stock photo. A slate, like a
   camera that has not rolled yet. */
.gw-media--placeholder {
  display: grid;
  place-items: center;
  background:
    repeating-linear-gradient(
      135deg,
      var(--gw-surface-3) 0 10px,
      var(--gw-surface-2) 10px 20px
    );
}
.gw-media__slate {
  text-align: center;
  padding: var(--gw-s-4);
  font-family: var(--gw-font-data);
  font-size: var(--gw-t-data);
  letter-spacing: var(--gw-track-data);
  text-transform: uppercase;
  color: var(--gw-text-faint);
}
.gw-media__slate strong {
  display: block;
  font-family: var(--gw-font-display);
  font-weight: 800;
  font-size: var(--gw-t-lg);
  letter-spacing: 0.02em;
  color: var(--gw-text-muted);
  margin-bottom: var(--gw-s-2);
}

/* The REC bug that sits on a rolling video. Broadcast vernacular, and it
   doubles as the "this is our own footage" signal. */
.gw-media__bug {
  position: absolute;
  top: var(--gw-s-3);
  left: var(--gw-s-3);
  z-index: 2;
  pointer-events: none;
}

/* ── STAT ────────────────────────────────────────────────────────────────
   Renders ONLY when the number is verified. media/js never invents a stat:
   if content/ucc-data.json marks it unverified, the block does not render. */
.gw-stat { text-align: left; }
.gw-stat__value {
  display: block;
  font-family: var(--gw-font-display);
  font-weight: 900;
  font-size: var(--gw-t-xl);
  line-height: 1;
  letter-spacing: var(--gw-track-display);
  color: var(--gw-text);
  font-variant-numeric: tabular-nums;
}
.gw-stat__label {
  display: block;
  margin-top: var(--gw-s-2);
  font-family: var(--gw-font-data);
  font-size: var(--gw-t-data);
  letter-spacing: var(--gw-track-data);
  text-transform: uppercase;
  color: var(--gw-text-faint);
}

/* ── STEPPER RAIL ────────────────────────────────────────────────────────
   Skeleton only. Session B owns the /tournaments funnel and spends the
   session's boldness there. Mobile = vertical timeline. Desktop = sticky
   rail. Never the reverse.                                                */
.gw-steps { position: relative; list-style: none; margin: 0; padding: 0; }
.gw-steps::before {
  content: '';
  position: absolute;
  left: 11px; top: 6px; bottom: 6px;
  width: 1px;
  background: var(--gw-rule);
}
.gw-step {
  position: relative;
  padding-left: calc(var(--gw-s-6) + var(--gw-s-2));
  padding-bottom: var(--gw-s-7);
}
.gw-step::before {
  content: '';
  position: absolute;
  left: 5px; top: 6px;
  width: 13px; height: 13px;
  border-radius: 50%;
  background: var(--gw-surface);
  border: 2px solid var(--gw-rule-strong);
}
.gw-step.is-live::before { border-color: var(--gw-accent); background: var(--gw-accent); }
.gw-step:last-child { padding-bottom: 0; }

@media (min-width: 900px) {
  .gw-steps--rail { position: sticky; top: var(--gw-s-8); }
}

/* ── REPLAY WIPE ─────────────────────────────────────────────────────────
   Section transition, CSS only, no JS, no parallax. A single sweep of the
   accent across the seam — the wipe a broadcast cuts on.                   */
.gw-wipe {
  height: 2px;
  border: 0;
  margin: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--gw-accent) 35%,
    var(--gw-punct) 50%,
    var(--gw-accent) 65%,
    transparent 100%
  );
  background-size: 240% 100%;
  background-position: 100% 0;
  transition: background-position 1.1s var(--gw-ease);
}
.gw-wipe.is-visible { background-position: 0 0; }
@media (prefers-reduced-motion: reduce) {
  .gw-wipe { transition: none; background-position: 0 0; }
}

/* ── THEME TOGGLE ────────────────────────────────────────────────────────*/
.gw-theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  border: 1px solid var(--gw-rule-strong);
  border-radius: var(--gw-r-sm);
  background: transparent;
  color: var(--gw-text);
  cursor: pointer;
  transition: background-color var(--gw-dur-fast) ease;
}
.gw-theme-toggle:hover { background: var(--gw-surface-3); }
/* One icon shows per theme. No JS needed to swap them. */
.gw-theme-toggle .gw-icon-dark  { display: none; }
html.gw-light .gw-theme-toggle .gw-icon-dark,
html[data-theme="light"] .gw-theme-toggle .gw-icon-dark  { display: block; }
html.gw-light .gw-theme-toggle .gw-icon-light,
html[data-theme="light"] .gw-theme-toggle .gw-icon-light { display: none; }
@media (prefers-color-scheme: light) {
  html:not(.gw-dark):not([data-theme="dark"]) .gw-theme-toggle .gw-icon-dark  { display: block; }
  html:not(.gw-dark):not([data-theme="dark"]) .gw-theme-toggle .gw-icon-light { display: none; }
}
