/* ============================================================
   GGhuman — arcade UI
   Black is the surface. White is the text. Blue belongs to the
   games that are actually playable, and to nothing else.
   ============================================================ */

:root{
  --bg:      #000;
  --panel:   #0a0a0c;
  --panel-2: #151519;
  --line:    rgba(255,255,255,.10);
  --line-2:  rgba(255,255,255,.22);

  --fg:      #fff;
  --fg-2:    rgba(255,255,255,.76);
  --fg-3:    rgba(255,255,255,.58);

  --blue:    #2b6cff;
  --blue-2:  #74a0ff;

  --ui:   "Archivo", system-ui, -apple-system, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", monospace;

  --edge: clamp(18px, 3.4vw, 56px);
  --ease: cubic-bezier(.16,1,.3,1);
}

*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; background:var(--bg); }
body{
  margin:0; background:var(--bg); color:var(--fg);
  font-family:var(--ui); font-size:16px; line-height:1.5;
  font-variation-settings:"wdth" 100;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
h1,h2,h3,h4,h5,h6,p,figure{ margin:0; }
img{ max-width:100%; display:block; }
a{ color:inherit; text-decoration:none; }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }
::selection{ background:var(--blue); color:#fff; }

/* ---------- type primitives ---------- */
.label{
  font-family:var(--mono); font-size:11px; letter-spacing:.2em;
  text-transform:uppercase; color:var(--fg-3);
}
.logotype{
  font-family:var(--ui); font-weight:800; text-transform:uppercase;
  letter-spacing:-.045em; line-height:.86;
  font-variation-settings:"wdth" 112, "wght" 800;
}

/* ---------- top bar ---------- */
.topbar{
  position:sticky; top:0; z-index:60;
  display:flex; align-items:center; gap:clamp(18px,3vw,44px);
  padding:0 var(--edge); height:62px;
  background:rgba(0,0,0,.86); backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line);
}
.topbar.floating{ position:absolute; background:none; backdrop-filter:none; border:0; left:0; right:0; }
.brand{ font-weight:800; font-size:17px; letter-spacing:-.03em;
  font-variation-settings:"wdth" 108,"wght" 800; white-space:nowrap; }
.brand i{ font-style:normal; font-weight:300; opacity:.7; }
.topbar nav{ display:flex; gap:clamp(14px,2vw,28px); font-size:13.5px; }
.topbar nav a{ color:var(--fg-3); transition:color .2s; }
.topbar nav a:hover, .topbar nav a[aria-current]{ color:var(--fg); }
.topbar .spacer{ flex:1; }
.topbar .play.sm + .profile{ margin-left:14px; }
.topbar .who{
  display:flex; align-items:center; gap:9px; font-family:var(--mono);
  font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--fg-3);
}
.topbar .who .pip{ width:26px; height:26px; border-radius:4px; background:var(--panel-2);
  border:1px solid var(--line-2); display:grid; place-items:center; font-size:10px; color:var(--fg); }
@media(max-width:720px){ .topbar nav{ display:none; } }

/* game-page top row: stays legible over bright art */
.top{ background:linear-gradient(180deg, rgba(0,0,0,.62) 0%, rgba(0,0,0,.26) 48%, transparent 100%); }

/* ---------- profile ---------- */
.profile{ position:relative; }
.profile-btn{ display:flex; align-items:center; gap:9px; padding:5px 11px 5px 5px;
  border-radius:999px; border:1px solid transparent; transition:.18s var(--ease); }
.profile-btn:hover, .profile-btn[aria-expanded="true"]{
  border-color:var(--line-2); background:rgba(255,255,255,.05); }
.profile-btn .pip{ width:26px; height:26px; border-radius:50%; background:var(--panel-2);
  border:1px solid var(--line-2); display:grid; place-items:center;
  font-family:var(--mono); font-size:10px; color:var(--fg); flex:0 0 auto; }
.profile-btn .handle{ font-family:var(--mono); font-size:11px; letter-spacing:.12em;
  text-transform:uppercase; color:var(--fg-3); }
.profile-btn:hover .handle{ color:var(--fg); }
.profile-btn svg{ width:9px; height:9px; color:var(--fg-3); transition:transform .2s; }
.profile-btn[aria-expanded="true"] svg{ transform:rotate(180deg); }

.profile-menu{ position:absolute; top:calc(100% + 10px); right:0; z-index:80;
  width:min(88vw,280px); padding:6px; border-radius:6px;
  /* opaque: at .97 the headline behind it showed through on small screens */
  background:#0b0b0e; border:1px solid var(--line-2);
  box-shadow:0 26px 60px -24px #000, 0 0 0 100vmax rgba(0,0,0,.001); }
.profile-menu[hidden]{ display:none; }
.pm-head{ display:flex; gap:12px; padding:12px 12px 14px; }
.pm-av{ width:40px; height:40px; border-radius:50%; flex:0 0 auto; display:grid;
  place-items:center; background:#f2e4c6; color:#1c1a16;
  font-size:14px; font-weight:800; font-variation-settings:"wdth" 104,"wght" 800; }
.pm-head > div{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.pm-head b{ font-size:14px; font-weight:600; }
.pm-head .pm-handle{ font-family:var(--mono); font-size:11px; color:var(--fg-3); }
.pm-head .pm-mail{ font-size:12px; color:var(--fg-3); overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.profile-menu hr{ border:0; height:1px; background:var(--line); margin:6px 0; }
.profile-menu a{ display:flex; align-items:center; justify-content:space-between;
  padding:9px 12px; border-radius:4px; font-size:13.5px; color:var(--fg-2);
  transition:.15s; }
.profile-menu a:hover{ background:rgba(255,255,255,.07); color:var(--fg); }
.profile-menu a span{ font-family:var(--mono); font-size:10px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--fg-3); }
.profile-menu a.danger:hover{ color:#ff9ba0; }

/* ---------- back link ---------- */
.back{
  display:inline-flex; align-items:center; gap:9px;
  font-family:var(--mono); font-size:11px; letter-spacing:.18em;
  text-transform:uppercase; color:var(--fg-3); transition:color .2s;
}
.back:hover{ color:var(--fg); }
.back svg{ width:14px; height:14px; }

/* ---------- the one button ---------- */
.play{
  display:inline-flex; align-items:center; justify-content:center; gap:11px;
  padding:0 30px; height:52px; border-radius:3px;
  background:var(--fg); color:#000;
  font-weight:700; font-size:15px; letter-spacing:.02em;
  font-variation-settings:"wdth" 105,"wght" 700;
  transition:transform .18s var(--ease), box-shadow .18s var(--ease);
}
.play svg{ width:15px; height:15px; }
.play:hover{ transform:translateY(-1px); box-shadow:0 0 0 3px rgba(255,255,255,.16); }
.play:active{ transform:translateY(0); }
.play.sm{ height:42px; padding:0 22px; font-size:13.5px; }

/* a text link, deliberately not a second button */
.textlink{
  font-size:14px; color:var(--fg-2); border-bottom:1px solid var(--line-2);
  padding-bottom:2px; transition:.2s;
}
.textlink:hover{ color:var(--fg); border-color:var(--fg); }

/* ---------- machine eyes ----------
   Two copies of the same plate, filtered down to only the strongly-red
   pixels. Because they are the same <img> with the same object-fit, they
   stay pinned to the robots at every viewport size without hand-placed
   coordinates. */
.eye-core, .eye-bloom{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; mix-blend-mode:screen; pointer-events:none;
}
/* The SVG filter belongs to the static image, while opacity belongs to this
   wrapper. Keeping those jobs on separate layers lets the browser cache the
   expensive filtered pixels and composite only opacity on each animation
   frame. Applying both filter and opacity to the image forces some renderers
   to rasterise the full plate continuously. */
.glow-motion{
  position:absolute; inset:0; width:100%; height:100%;
  pointer-events:none; z-index:4;
  mix-blend-mode:screen;
  contain:paint; will-change:opacity; transform:translateZ(0);
}
.glow-motion > .eye-core,
.glow-motion > .eye-bloom{
  z-index:auto;
  /* Blend on the motion layer, matching the original filter/blend/opacity
     ordering while leaving the filtered child cacheable. */
  mix-blend-mode:normal;
  /* GG.redglow animates the wrapper. The filtered child must remain static. */
  opacity:1 !important;
}
/* Full-screen heroes use tiny, pre-filtered transparent crops. They already
   contain the screen-blended glow colour, so normal alpha compositing avoids a
   viewport-sized blend pass on every frame. */
.glow-motion.glow-baked{ mix-blend-mode:normal; }
.eye-core[data-glow-baked],
.eye-bloom[data-glow-baked]{ filter:none !important; }
/* the glow must sit above the scrim, or the scrim dims the very thing it is
   there to show */
.stage .eye-core, .stage .eye-bloom, .stage .glow-motion{ z-index:4; }
.eye-core{  filter:url(#gg-red-core); }
.eye-bloom{ filter:url(#gg-red-bloom); opacity:.45; }
/* plates whose machines glow cyan in the source */
.eye-core.mach{  filter:url(#gg-mach-core); }
.eye-bloom.mach{ filter:url(#gg-mach-bloom); }
/* every glow layer must share the plate's fit and position, or it drifts off
   the robots. Both default to cover, matching .plate. */
.eye-core, .eye-bloom{ object-position:50% 46%; }
/* Settler Rush: the citadel's red is muted enough that the strong key misses
   it, so it uses a softer key masked to the ridge. */
.eye-core.warm{  filter:url(#gg-warm-core); }
.eye-bloom.warm{ filter:url(#gg-warm-bloom); }
.eye-core.warm, .eye-bloom.warm{ object-position:50% 44%; }

/* Poker: the plate's machines glow cyan. The filter converts that to
   machine red exactly where it already sits — the eye ring, the panel seams,
   the specks down the arm — rather than as one placed dot. The threshold on
   its own is enough to skip the shark's shirt and the fox's jacket. */
.eye-core.mach, .eye-bloom.mach{
  /* masked to the stag only — the rabbit sits behind the headline and smeared
     red across the type. GG.maskFeature places it from image coordinates. */
  object-position:50% 45%;
}

/* Hand-placed machine eyes, for plates where the art has no glow to amplify.
   Positioned by GG.pointAt from image coordinates, so hero and thumbnail share
   one set of numbers. */
.spot{ position:absolute; transform:translate(-50%,-50%); border-radius:50%;
  pointer-events:none; mix-blend-mode:screen; z-index:4; }
.spot-core{ background:radial-gradient(circle, #ff6a44 0%, rgba(255,50,26,.8) 32%, transparent 66%); }
.spot-bloom{ background:radial-gradient(circle, rgba(255,60,32,.55) 0%, rgba(255,26,10,.18) 40%, transparent 72%);
  opacity:.45; }
/* Last Vote sits in a quiet blue plate and a hot flash reads as a bug light.
   Lower the colour alpha rather than the element opacity, because the
   animation drives opacity and would overwrite it.

   Two tiers, because the hero and the thumbnail want different things: at hero
   size the eyes are a detail you notice on a second look, at thumbnail size the
   same treatment turns into a bright dot on a small dark card. */
.spot-core.subtle{ background:radial-gradient(circle, rgba(255,138,100,.82) 0%, rgba(255,66,38,.42) 36%, transparent 70%); }
.spot-bloom.subtle{ background:radial-gradient(circle, rgba(255,74,44,.3) 0%, rgba(255,30,12,.1) 42%, transparent 74%);
  opacity:.22; }

.spot-core.faint{ background:radial-gradient(circle, rgba(255,140,102,.6) 0%, rgba(255,70,42,.28) 38%, transparent 72%); }
.spot-bloom.faint{ background:radial-gradient(circle, rgba(255,76,46,.2) 0%, rgba(255,34,16,.06) 44%, transparent 76%);
  opacity:.14; }

/* ---------- live indicator ---------- */
.live{
  display:inline-flex; align-items:center; gap:7px;
  font-family:var(--mono); font-size:11px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--blue-2);
}
.live i{ width:6px; height:6px; border-radius:50%; background:var(--blue);
  box-shadow:0 0 8px var(--blue); animation:pip 1.8s infinite; }
@keyframes pip{ 0%,100%{opacity:1} 50%{opacity:.3} }

/* ---------- stat row ---------- */
.stats{ display:flex; gap:clamp(20px,3.4vw,48px); flex-wrap:wrap; }
.stats .k{ font-family:var(--mono); font-size:10.5px; letter-spacing:.2em;
  text-transform:uppercase; color:var(--fg-3); display:block; }
.stats .v{ font-size:19px; font-weight:600; letter-spacing:-.01em; margin-top:3px; display:block; }

/* ---------- section head ---------- */
.sect{ display:flex; align-items:center; gap:16px; margin:0 0 18px; }
.sect h2{ margin:0; font-size:13px; font-weight:600; letter-spacing:.16em;
  text-transform:uppercase; font-family:var(--mono); color:var(--fg-2); white-space:nowrap; }
.sect .n{ font-family:var(--mono); font-size:11px; color:var(--fg-3); }
.sect hr{ flex:1; border:0; height:1px; background:var(--line); margin:0; }

/* ---------- game grid ---------- */
.grid{
  display:grid; gap:14px;
  grid-template-columns:repeat(auto-fill, minmax(238px, 1fr));
}
@media(max-width:520px){ .grid{ grid-template-columns:repeat(2,1fr); gap:10px; } }

.tile{
  position:relative; aspect-ratio:3/4; overflow:hidden; border-radius:4px;
  background:var(--panel); border:1px solid var(--line);
  display:flex; flex-direction:column; justify-content:flex-end;
  transition:transform .32s var(--ease), border-color .32s, box-shadow .32s;
  isolation:isolate;
}
.tile canvas, .tile .art{ position:absolute; inset:0; width:100%; height:100%; z-index:0; }
.tile .fade{ position:absolute; inset:0; z-index:1;
  background:linear-gradient(180deg, transparent 0%, rgba(0,0,0,.12) 44%, rgba(0,0,0,.72) 74%, rgba(0,0,0,.96) 100%); }
.tile .body{ position:relative; z-index:4; padding:16px; display:flex; flex-direction:column; gap:6px; }
.tile .name{ font-size:clamp(19px,1.5vw,23px); }
.tile .meta{ font-family:var(--mono); font-size:10.5px; letter-spacing:.11em;
  text-transform:uppercase; color:var(--fg-3); }
.tile .tag{
  position:absolute; top:12px; right:12px; z-index:3;
  font-family:var(--mono); font-size:9.5px; letter-spacing:.18em; text-transform:uppercase;
  padding:4px 8px; border-radius:2px; border:1px solid var(--line-2); color:var(--fg-3);
  background:rgba(0,0,0,.45);
}

/* playable */
.tile.on{ cursor:pointer; }
.tile.on:hover{ transform:translateY(-6px); border-color:var(--blue);
  box-shadow:0 18px 44px -16px rgba(43,108,255,.6); }
.tile.on .live{ font-size:10px; }
/* Play: a plain rectangle centred over the art, revealed on hover. It overlays
   rather than expanding the card, so nothing reflows and the title stays put. */
.tile .cta{
  position:absolute; inset:0; z-index:3; display:grid; place-items:center;
  background:linear-gradient(180deg, rgba(0,0,0,.42) 0%, rgba(0,0,0,.30) 62%, transparent 100%);
  opacity:0; pointer-events:none;
  transition:opacity .26s var(--ease);
}
.tile.on:hover .cta{ opacity:1; }
.tile .cta span{
  padding:13px 34px; background:var(--fg); color:#000; border-radius:0;
  font-weight:700; font-size:12.5px; letter-spacing:.18em; text-transform:uppercase;
  font-variation-settings:"wdth" 104,"wght" 700;
  transform:translateY(8px);
  transition:transform .3s var(--ease);
  box-shadow:0 10px 30px -10px rgba(0,0,0,.9);
}
.tile.on:hover .cta span{ transform:translateY(0); }

/* not yet playable — greyscale, no blue, no CTA */
.tile.soon{ cursor:default; }
.tile.soon .art{ filter:grayscale(1); opacity:.5; }
.tile.soon .name{ color:var(--fg-2); }
.tile.soon:hover{ border-color:var(--line-2); }

/* ---------- mock-kit nav (not part of the product) ---------- */
.kit{
  position:fixed; right:14px; bottom:14px; z-index:9000;
  display:flex; flex-direction:column; gap:1px; padding:5px;
  background:rgba(10,10,12,.92); border:1px solid var(--line); border-radius:8px;
  font-family:var(--mono); font-size:10px; letter-spacing:.1em; text-transform:uppercase;
  opacity:.28; max-height:28px; overflow:hidden; transition:opacity .25s;
}
.kit::before{ content:"mocks"; padding:5px 11px; color:var(--fg-3); text-align:center; }
.kit:hover{ opacity:1; max-height:460px; }
.kit a{ padding:7px 12px; border-radius:4px; color:var(--fg-3); white-space:nowrap; }
.kit a:hover{ color:var(--fg); background:var(--panel-2); }
.kit a.on{ background:var(--fg); color:#000; }
.kit hr{ border:0; height:1px; background:var(--line); margin:4px 0; }

@media (prefers-reduced-motion:reduce){
  *{ animation-duration:.01ms !important; transition-duration:.01ms !important; }
}
