/* The hub (hero): DESIGN §15.1, the layout of §11.2, UIKIT 2, 9-14, 17; KITCSS §7 "Hero DOM twins".
   Owner: hero (design/CONTRACTS.md). Loaded by site/index.html; portal/build.sh versions it.

   The DOM owns the layout (§11.2): the column (live total, wordmark, tagline, the featured block) and the stage slots the
   WebGPU hub fits its portals into - #hero-portal (the featured opening at rest), the .hub-more links (small portals) and the
   .hub-soon slots (closed SOON membranes). kit.css paints every component in its CSS theme, nogpu.css places the baked hub
   stills (.hub-still: the boot frame, no WebGPU, the hub3d kill switch). This file only lays the hub out and styles the text
   that sits on the bare void (tagline, description, meta, "1 / 4": visible DOM, DESIGN §16.1 R1).

   Layouts: wide (>= 760 px and aspect >= 1.1; 1440 x 900 = boards/hero-desktop.png), md (760-1199), portrait / phones
   (< 760 or aspect < 1.1; boards/hero-mobile.png) and short landscape (coarse, under 500 px tall). */

#portal-hero {
  /* the first screen (§11.2): clamp(640px, 100svh, 1000px). The hop pad (toolbar region, after this section) docks into
     its bottom 104 px (toolbar.css: the sentinel's margin-top -104 px), so pad top = hero height - 104: that band stays free */
  --hub-full: clamp(640px, 100svh, 1000px);
  --hub-pad: 104px;
  --hub-x: max(72px, calc(env(safe-area-inset-left, 0px) + 16px));
  --hub-r: max(36px, calc(env(safe-area-inset-right, 0px) + 16px));
  --hub-col: clamp(440px, 38vw, 548px);
  --hub-wm: clamp(56px, calc(var(--hub-col) / 6.25), 112px);   /* the wordmark master's size (88 at 1440) */
  --hub-stage-x: calc(var(--hub-x) + var(--hub-col) + 40px);
  position: relative;
  z-index: 3;
  height: var(--hub-full);
  color: var(--text);
  font-family: var(--f-body);
  -webkit-font-smoothing: antialiased;
  pointer-events: none;   /* #portal-page is click-through; controls and text opt back in below */
}
#portal-hero :is(a, button, .hub-tagline, .spotlight-title, .spotlight-desc, .hub-meta, .k-rot__count, .hub-state p, #portal-live) {
  pointer-events: auto;
}
:where(#portal-hero) :is(p, h1, h2) { margin: 0; }

/* ---- the column: live total, wordmark + tagline --------------------------------------------------------------------- */
/* the column's content starts 4 px in (design/src/hub.js: colX + 4); the wordmark's origin sits at colX */
.hub-head { position: absolute; left: calc(var(--hub-x) + 4px); top: 64px; width: calc(var(--hub-col) - 4px); }
.hub-total { margin: 0; }
.hub-brand { position: relative; width: calc(var(--hub-wm) * 6.4545); margin: 10px 0 0 calc(-4px - var(--hub-wm) * 0.10227); }
/* The <h1> is the wordmark's twin: its text stays "adventure.io" for screen readers and search; the inline SVG is the boot
   frame's wordmark (the same master as the GPU sprite, ART.md §3). */
.hub-wordmark { display: block; width: 100%; line-height: 0; }
.hub-wordmark__art { display: block; width: 100%; height: auto; overflow: visible; }
.hub-wordmark__art--small { display: none; }
/* the tagline sits right of ".io" (meta ioX + ioW of the master), two lines */
.hub-tagline {
  position: absolute; left: calc(23.85% + 16px); top: 55.5%;
  font: 500 max(15px, calc(var(--hub-wm) * .165))/1.35 var(--f-body); color: var(--text-hi);
}
.hub-tagline > span { display: block; white-space: nowrap; }

/* ---- the featured block --------------------------------------------------------------------------------------------- */
.hub-spot {
  position: absolute; left: calc(var(--hub-x) + 4px); width: calc(var(--hub-col) - 4px);
  top: clamp(292px, calc(330px - (900px - var(--hub-full)) * .2), 372px);
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center;
  grid-template-areas: "sticker rot" "title title" "desc desc" "keys keys" "meta meta" "state state";
}
.hub-spot > * { min-width: 0; }   /* nothing in the column may widen it past --hub-col (it would run under the portal) */
.hub-sticker { grid-area: sticker; justify-self: start; --k-rot: -3deg; }
.hub-rot { grid-area: rot; justify-self: start; margin-left: 26px; }
.hub-rot .k-rot__count { white-space: nowrap; flex: none; }   /* "1 / 4" is one readout (DESIGN §2.1) */
.spotlight-title {
  grid-area: title; margin-top: 26px; max-width: 100%;
  font: 800 var(--fs-display-hero)/var(--lh-display-hero) var(--f-display); color: var(--text-hi);
  --k-lip: var(--tl-display-hero);
  -webkit-text-stroke: max(1.2px, .035em) var(--ink); paint-order: stroke fill;
  text-shadow: 0 var(--k-lip) 0 var(--ink), .5px var(--k-lip) 0 var(--ink), -.5px var(--k-lip) 0 var(--ink), 0 calc(var(--k-lip) * .5) 0 var(--ink);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; padding-bottom: 6px;
  overflow-wrap: anywhere;
}
.spotlight-title.is-long { font-size: 52px; --k-lip: 4px; }
.spotlight-desc {
  grid-area: desc; margin-top: -11px; max-width: 480px;
  font: 400 var(--fs-body-l)/var(--lh-body-l) var(--f-body); color: var(--text);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
.hub-keys { grid-area: keys; display: flex; flex-wrap: wrap; align-items: center; gap: 24px; margin-top: 18px; }
.spotlight-play { min-width: 212px; }
.hub-jump { max-width: 280px; }
.hub-meta { grid-area: meta; display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; margin-top: 30px; min-height: 30px; }
.spotlight-meta { font: 500 var(--fs-meta)/var(--lh-meta) var(--f-body); color: var(--text-dim); }
.spotlight-meta:empty { display: none; }
.hub-rot .k-rot__pause .hub-ico-resume, .hub-rot.is-stopped .k-rot__pause .hub-ico-pause { display: none; }
.hub-rot.is-stopped .k-rot__pause .hub-ico-resume { display: inline-block; }

/* the catalog error / empty / 404 states replace the featured block's copy (§15.1, §15.10) */
.hub-state { grid-area: state; display: grid; justify-items: start; gap: 10px; }
.hub-state[hidden] { display: none; }
/* the state pictures at their own size, never taller than 200 px (the 0-game Munch is a tall picture): the title, the line
   and the key stay above the docked pad */
.hub-state__art { width: auto; height: auto; max-width: min(100%, 384px); max-height: 200px; margin-bottom: 6px; }
.hub-state__art:not([src^="/"]) { display: none; }
.hub-state__title { font: 800 var(--fs-display-state-l)/var(--lh-display-state-l) var(--f-display); color: var(--text-hi);
  --k-lip: var(--tl-display-state-l); -webkit-text-stroke: max(1.2px, .035em) var(--ink); paint-order: stroke fill;
  text-shadow: 0 var(--k-lip) 0 var(--ink), .5px var(--k-lip) 0 var(--ink), -.5px var(--k-lip) 0 var(--ink); }
.hub-state__text { font: 400 var(--fs-body-l)/var(--lh-body-l) var(--f-body); color: var(--text); }
.hub-state__title:empty, .hub-state__text:empty { display: none; }
.hub-state .k-key { margin-top: 12px; }
#spotlight[data-state="error"] :is(.hub-sticker, .spotlight-title, .spotlight-desc, .hub-keys, .hub-meta, .hub-rot),
#spotlight[data-state="empty"] :is(.hub-sticker, .spotlight-title, .spotlight-desc, .hub-keys, .hub-meta, .hub-rot),
#spotlight[data-state="notfound"] :is(.hub-sticker, .spotlight-title, .spotlight-desc, .hub-keys, .hub-meta, .hub-rot) { display: none; }
#spotlight[data-state="single"] .hub-rot { display: none; }

/* ---- the stage: the featured opening (the slot the GPU fits its portal into) ------------------------------------------ */
/* x from the column's right + 40 to W - 36, y 80 to (pad top - 250) with small portals, else - 40; the opening is 1.68 : 1,
   contained and centred (744 x 443 at 1440 x 900). */
.hub-stage { position: absolute; left: var(--hub-stage-x); right: var(--hub-r); top: 80px; bottom: calc(var(--hub-pad) + 40px); container-type: size; }
/* A stage taller than 1440 x 900's (466 px) grows the opening less than its height (87.6 px + 76.4 %): the rim above it
   (about 5.5 % of its height, + the bob) stays clear of the header cluster at y 22-67 on wide screens (1920 x 1080: 874 x
   520 at y 103), and 1440 x 900 keeps the board's 744 x 443 at y 91 (DESIGN §11.2). */
#hero-portal {
  position: absolute; inset: 0; margin: auto;
  width: min(100cqw, 168cqh, calc(147.2px + 128.35cqh)); height: min(100cqh, 59.5238cqw, calc(87.6px + 76.4cqh));
  pointer-events: auto; cursor: pointer; outline: none;
}
/* small portals and a second SOON portal only on a tall wide hub (§11.2: hero >= 860 and W >= 1200) */
.hub-more { display: none; }
.hub-soon { display: none; }
.hub-soon__slot { position: absolute; }

@media (min-width: 760px) and (min-aspect-ratio: 11/10) {
  .hub-soon { display: block; }
  /* one SOON membrane in the void above the wordmark, one more under the column on a tall hub */
  .hub-soon__slot[data-soon="0"] { left: calc(var(--hub-x) + min(368px, var(--hub-col) - 150px)); top: 41px; width: 60px; height: 34px; }
  .hub-soon__slot[data-soon="1"] { display: none; }
}
@media (min-width: 1200px) and (min-height: 860px) and (min-aspect-ratio: 11/10) {
  .hub-stage { bottom: calc(var(--hub-pad) + 250px); }
  .hub-more {
    display: flex; justify-content: center; gap: 34px;
    position: absolute; left: var(--hub-stage-x); right: var(--hub-r); top: calc(100% - var(--hub-pad) - 218px);
  }
  .hub-soon__slot[data-soon="1"] { display: block; left: calc(var(--hub-stage-x) - 110px); top: calc(100% - var(--hub-pad) - 151px); width: 52px; height: 28px; }
}

/* ---- small portal links (UIKIT 17): static slots covering the opening, the plate and (touch) the Play pill ----------- */
.hub-link {
  display: flex; flex-direction: column; align-items: center; width: 196px; padding: 12px 0 6px;
  border-radius: 28px; text-decoration: none; color: inherit;
}
.hub-link[hidden] { display: none; }
.hub-link__window { width: 144px; height: 100px; flex: none; }
.hub-plate { margin-top: 14px; max-width: 196px; pointer-events: none; }
.hub-plate .k-plate__count[hidden] { display: none; }
/* the Play pill: under the count on touch (always shown, UIKIT 11); on fine pointers the GPU pops it at the opening's
   centre on hover / focus, and in the CSS theme it pops there too */
.hub-plate__play { display: none; }
@media (hover: none) {
  .hub-link .hub-plate__play { display: inline-flex; position: static; opacity: 1; transform: none; margin-top: 4px; }
}
/* the GPU paints this link's focus ring around its projected rim (hub3d marks the hub data-hub="gpu") */
html.gpu-paint #portal-hero[data-hub="gpu"] .hub-link:focus-visible { outline-color: transparent; box-shadow: none; }

/* ---- md (760-1199): a 44 % column, no small portals ------------------------------------------------------------------- */
@media (min-width: 760px) and (max-width: 1199.98px) and (min-aspect-ratio: 11/10) {
  #portal-hero { --hub-x: max(36px, calc(env(safe-area-inset-left, 0px) + 16px)); --hub-col: max(360px, 44vw);
    --hub-wm: clamp(56px, calc(var(--hub-col) / 6.25), 96px); }
  .spotlight-title { font-size: 52px; --k-lip: 4px; }
  .spotlight-title.is-long { font-size: 44px; }
  .hub-soon__slot[data-soon="0"] { left: calc(var(--hub-x) + var(--hub-col) - 70px); top: 30px; }
}

/* ---- short desktop heights: keep the column above the pad ------------------------------------------------------------ */
@media (min-width: 760px) and (min-aspect-ratio: 11/10) and (max-height: 779.98px) {
  .spotlight-title { font-size: 52px; --k-lip: 4px; }
  .spotlight-title.is-long { font-size: 44px; }
  .spotlight-desc { -webkit-line-clamp: 1; }
  .hub-keys { margin-top: 18px; }
  .hub-meta { margin-top: 20px; }
}

/* ---- portrait / phones (< 760 or aspect < 1.1): one flowing column, max 600 wide; a phone held sideways (coarse, under
   500 px tall) takes the short-landscape layout below instead, whatever its width (667 x 375, 740 x 360) -------------- */
@media (max-aspect-ratio: 1099/1000), (max-width: 759.98px) and (min-height: 500px), (max-width: 759.98px) and (pointer: fine),
  (max-width: 759.98px) and (pointer: none) {
  #portal-hero {
    --hub-x: max(16px, calc(env(safe-area-inset-left, 0px) + 8px));
    --hub-r: max(16px, calc(env(safe-area-inset-right, 0px) + 8px));
    height: auto; max-width: calc(600px + var(--hub-x) + var(--hub-r)); margin: 0 auto;
    overflow-x: clip;   /* the baked still reaches past the slot (nogpu.css): never a horizontal page scroll */
    padding: max(12px, calc(env(safe-area-inset-top, 0px) + 8px)) var(--hub-r) 24px var(--hub-x);
    display: flex; flex-direction: column;
  }
  .hub-head { position: static; order: 1; width: auto; min-height: 44px; }
  .hub-total { display: none !important; }
  /* the small wordmark (25 px, one line), clear of the header's two 44 px icon keys at 320 px */
  /* the small mark's origin is 4 viewBox units in (of 285) */
  .hub-brand { width: min(192px, calc(100vw - 184px)); margin: 7px 0 0 calc(min(192px, 100vw - 184px) * -0.014); }
  .hub-wordmark__art--master { display: none; }
  .hub-wordmark__art--small { display: block; }
  .hub-tagline { position: static; margin: 18px 0 0 calc(min(192px, 100vw - 184px) * 0.014); width: max-content; max-width: calc(100vw - 32px); font-size: 15px; }
  .hub-tagline > span { display: inline; white-space: normal; }
  .hub-stage { position: relative; order: 2; left: auto; right: auto; top: auto; bottom: auto; margin-top: 21px; container-type: normal; }
  /* the opening is the window less 4 px a side (design/src/hub.js K.hubFeaturedPhone: rx = ww / 2 - 4) */
  #hero-portal { position: relative; inset: auto; margin: 0 auto; width: calc(100% - 8px); height: auto; aspect-ratio: 350 / 216; }
  .hub-spot {
    position: static; order: 3; width: auto; margin-top: 24px;
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "rot" "sticker" "title" "desc" "meta" "keys" "state";
  }
  /* right of the box art (design/src/hub.js K.hubPhone), one line on every phone: the row is 272 px (count, four 44 px
     bulbs, the pause key), so its 80 px offset gives way below 354 px of column (it stays clear of the box art's corner) */
  .hub-rot { justify-self: center; margin: 4px 0 18px clamp(0px, calc(100% - 274px), 80px); }
  .hub-rot .k-rot__count { margin-right: 10px; }
  .hub-rot .k-rot__pause { margin-left: 8px; }
  /* a state (404, error, empty) starts right under the window: clear of the drip tips, which grow with the window (DESIGN §7) */
  .hub-state { margin-top: max(28px, calc((min(600px, 100vw - 32px) - 8px) * 0.12 - 18px)); }
  .spotlight-title { margin-top: 20px; font-size: 42px; --k-lip: 4px; }
  .spotlight-title.is-long { font-size: 38px; }
  .spotlight-desc { margin-top: -5px; font-size: 16px; line-height: 23px; }
  .hub-meta { margin-top: 10px; gap: 6px 12px; }
  .spotlight-meta > span:nth-child(n + 3) { display: none; }   /* the short meta: two parts */
  .hub-keys { flex-direction: column; align-items: stretch; gap: 18px; margin-top: 16px; }
  .spotlight-play, .hub-jump { width: 100%; max-width: none; --k-h: 56px; }
  .hub-more { display: flex; order: 4; justify-content: center; gap: 12px; margin-top: 26px; }
  .hub-link:nth-child(n + 3) { display: none; }
  .hub-link { width: min(170px, calc(50% - 6px)); }
  .hub-link__window { width: 140px; height: 96px; }
}
/* wider than a phone, the window (and its drips with it) grows up to 1.7x: the rotation row moves under the drip tips
   instead of sitting between them (DESIGN §7: drips never over text) */
@media (min-width: 470px) and (max-width: 759.98px) and (min-height: 500px), (min-width: 470px) and (max-aspect-ratio: 1099/1000) {
  .hub-rot { margin-top: calc((min(600px, 100vw - 32px) - 8px) * 0.12 - 18px); }
}
@media (min-width: 760px) and (max-aspect-ratio: 1099/1000) {
  #portal-hero { padding-bottom: calc(var(--hub-pad) + 32px); }   /* the in-page pad docks 104 px into the hub */
}
@media (max-width: 359.98px) {
  .hub-link__window { width: 124px; height: 85px; }
}
/* narrow phones (and 400 % zoom): the description is never cut (WCAG 1.4.10 reflow), it wraps onto as many lines as it needs */
@media (max-width: 399.98px) {
  .spotlight-desc { display: block; -webkit-line-clamp: none; overflow: visible; }
}

/* ---- short portrait screens (a phone in Safari with its bars, an SE): Play now stays on the first screen, above the dock
   (70 + max(12, inset + 6) + 16 px from the bottom). Tighter gaps, Play now before the meta line, and the window gives up
   height to whatever the screen lacks (never below 120 px); under 620 px tall the description follows Play now. ------- */
@media (max-aspect-ratio: 1099/1000) and (max-height: 799.98px) {
  .hub-tagline { margin-top: 8px; }
  .hub-stage { margin-top: 12px; }
  /* a smaller window keeps the board's left edge (x 20), so the box art on its lower-left rim (scaled with it) stays clear
     of the rotation row on its right */
  #hero-portal {
    margin: 0 4px;
    width: min(100% - 8px, max(194px, (100svh - var(--nogpu-h, 0px) - max(12px, env(safe-area-inset-top, 0px) + 8px)
      - max(12px, env(safe-area-inset-bottom, 0px) + 6px) - 442px) * 1.6204));
  }
  #hero-portal > .hub-still__art { left: -1.7143%; top: 62.037%; width: 21.714%; height: 52.778%; }
  .hub-spot { margin-top: 12px; grid-template-areas: "rot" "sticker" "title" "desc" "keys" "meta" "state"; }
  .hub-rot { margin-top: 2px; margin-bottom: 8px; }
  .spotlight-title { margin-top: 10px; }
  .hub-keys { margin-top: 12px; }
  .hub-meta { margin-top: 12px; }
}
/* the no-WebGPU banner (66 px on phones) takes the same room from a taller screen */
@media (max-aspect-ratio: 1099/1000) and (min-height: 800px) and (max-height: 899.98px) {
  html.nogpu-banner .hub-tagline { margin-top: 8px; }
  html.nogpu-banner .hub-stage { margin-top: 12px; }
  html.nogpu-banner #hero-portal {
    margin: 0 4px;
    width: min(100% - 8px, max(194px, (100svh - var(--nogpu-h, 0px) - max(12px, env(safe-area-inset-top, 0px) + 8px)
      - max(12px, env(safe-area-inset-bottom, 0px) + 6px) - 442px) * 1.6204));
  }
  html.nogpu-banner #hero-portal > .hub-still__art { left: -1.7143%; top: 62.037%; width: 21.714%; height: 52.778%; }
  html.nogpu-banner .hub-spot { margin-top: 12px; grid-template-areas: "rot" "sticker" "title" "desc" "keys" "meta" "state"; }
  html.nogpu-banner .hub-rot { margin-top: 2px; margin-bottom: 8px; }
  html.nogpu-banner .spotlight-title { margin-top: 10px; }
  html.nogpu-banner .hub-keys { margin-top: 12px; }
  html.nogpu-banner .hub-meta { margin-top: 12px; }
}
@media (max-aspect-ratio: 1099/1000) and (max-height: 619.98px) {
  #hero-portal {
    width: min(100% - 8px, max(194px, (100svh - var(--nogpu-h, 0px) - max(12px, env(safe-area-inset-top, 0px) + 8px)
      - max(12px, env(safe-area-inset-bottom, 0px) + 6px) - 401px) * 1.6204));
  }
  .hub-spot { grid-template-areas: "rot" "sticker" "title" "keys" "desc" "meta" "state"; }
  .spotlight-desc { margin-top: 12px; }
}

/* ---- short landscape (coarse, under 500 px tall): the column beside a 16:9 window; the dock is the pad -------------- */
@media (pointer: coarse) and (max-height: 499.98px) and (min-aspect-ratio: 11/10) {
  #portal-hero { overflow-x: clip; --hub-full: 100svh; --hub-pad: 0px; --hub-x: max(16px, calc(env(safe-area-inset-left, 0px) + 8px));
    --hub-r: max(16px, calc(env(safe-area-inset-right, 0px) + 8px)); --hub-col: calc(50vw - var(--hub-x) - 20px); }
  .hub-head { top: max(12px, calc(env(safe-area-inset-top, 0px) + 8px)); }
  .hub-total, .hub-tagline, .hub-soon, .hub-more, .spotlight-meta { display: none !important; }
  .hub-brand { width: 192px; margin-top: 0; }
  .hub-wordmark__art--master { display: none; }
  .hub-wordmark__art--small { display: block; }
  /* the column stays inside its half: the rotation row has its own line, the live pill sits beside Play now */
  .hub-spot { top: 64px; grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: "sticker sticker" "rot rot" "title title" "desc desc" "keys meta" "state state"; }
  .hub-spot:has(.hub-jump:not([hidden])) { grid-template-areas: "sticker sticker" "rot rot" "title title" "desc desc" "keys keys" "state state"; }
  .hub-spot:has(.hub-jump:not([hidden])) .hub-meta { display: none; }
  .hub-rot { justify-self: start; margin: 6px 0 0; }
  .hub-rot .k-rot__count { margin-right: 10px; }
  .hub-rot .k-rot__pause { margin-left: 8px; }
  .spotlight-title { margin-top: 8px; font-size: 30px; --k-lip: 3px; -webkit-line-clamp: 1; }
  .spotlight-desc { margin-top: 4px; max-width: 100%; font-size: 15px; line-height: 21px; -webkit-line-clamp: 1; }
  .hub-keys { margin-top: 12px; gap: 12px; }
  .spotlight-play { --k-h: 48px; }
  .hub-meta { margin: 12px 0 0 16px; align-self: center; }
  /* the window starts under the header keys (top right, 44 px tall), never under them */
  .hub-stage { left: 50vw; top: max(64px, calc(env(safe-area-inset-top, 0px) + 60px)); bottom: 84px; }
  #hero-portal { width: min(100cqw, 177.78cqh); height: min(100cqh, 56.25cqw); }
}

/* the narrowest phones held sideways (568 x 320): the column is under 270 px, the bulbs and the pause key alone fit (their
   names say "Show OpenTyrian, 1 of 4") */
@media (pointer: coarse) and (max-height: 499.98px) and (min-aspect-ratio: 11/10) and (max-width: 599.98px) {
  .hub-rot .k-rot__count { display: none; }
}

/* ---- Reduce motion: the swap is instant; the sticker never wiggles ------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  html:not([data-motion="full"]) .hub-sticker { animation: none; }
}
html[data-motion="reduce"] .hub-sticker { animation: none; }

/* ---- forced colours: the renderer never starts; the CSS theme with system colours ------------------------------------- */
@media (forced-colors: active) {
  /* the art keeps its own cream + ink (forced fills turn the letters into blobs); it reads on Canvas like the box art */
  .hub-wordmark__art { forced-color-adjust: none; }
  .spotlight-title, .hub-state__title { -webkit-text-stroke: 0; text-shadow: none; }
}

/* goo:stills (generated by node portal/src/hero/gen-goo-stills.mjs from the kit's goo styles: do not edit this block)
   The boot frame's hub stills wear their game's goo tint, so the still -> GPU swap keeps the colour (GOO-VARIANTS §7): the
   featured rim through #hub-goo-<style> (the goo only: Stalks, the eyes and the ink keep theirs), the small rims and the box
   art's glob through gooFilter() (rest / awake). Not in the CSS theme (house, GOO-VARIANTS §12 q3), not on SOON / empty. */
#portal-hero :is(#hero-portal, .hub-link):is([data-slug="satsuma"], [data-slug="glest"], [data-slug="wyrmsun"]) {
  --hub-goo-still: url(#hub-goo-lacquer); --hub-goo-awake: hue-rotate(-6deg) saturate(1.26) brightness(0.94); }
#portal-hero :is(#hero-portal, .hub-link):is([data-slug="tyrian"], [data-slug="vigil"], [data-slug="racing-simulation"], [data-slug="king-of-the-cows"], [data-slug="flight64"]) {
  --hub-goo-still: url(#hub-goo-fizz); --hub-goo-awake: hue-rotate(15deg) saturate(0.9) brightness(1.12); }
#portal-hero :is(#hero-portal, .hub-link):is([data-slug="knight"], [data-slug="larkinor"], [data-slug="runescape"], [data-slug="ultimate-adventure"]) {
  --hub-goo-still: url(#hub-goo-tar); --hub-goo-awake: hue-rotate(5deg) saturate(0.68) brightness(0.79); --hub-goo-rest: hue-rotate(5deg) saturate(0.68) brightness(0.82); }
#portal-hero :is(#hero-portal, .hub-link):is([data-slug="spindizzy"], [data-slug="fantasy-kingdom-sim"], [data-slug="dopewars"], [data-slug="dopewars-classic"], [data-slug="dopewars-nyc"], [data-slug="dopewars-world"], [data-slug="cuteland"], [data-slug="deaddrop"], [data-slug="realm-trader"], [data-slug="lbreakouthd"]) {
  --hub-goo-still: url(#hub-goo-jelly); --hub-goo-awake: hue-rotate(-6deg) saturate(1.22) brightness(1.1); }
#portal-hero :is(#hero-portal, .hub-link):is([data-slug="ancient-space-empires"], [data-slug="star-trader"], [data-slug="dune-imperium-eternal"], [data-slug="ur-quan-masters"]) {
  --hub-goo-still: url(#hub-goo-zerog); --hub-goo-awake: hue-rotate(18deg) saturate(0.86) brightness(0.92); }
#portal-hero :is(#hero-portal, .hub-link):is([data-slug="anterra"], [data-slug="world-engine"], [data-slug="economics-simulation"]) {
  --hub-goo-still: url(#hub-goo-sap); --hub-goo-awake: hue-rotate(-14deg) saturate(1.12) brightness(0.84); }
#portal-hero :is(#hero-portal, .hub-link):is([data-slug="cube"], [data-slug="overrun"], [data-slug="xonotic"], [data-slug="ioquake3"], [data-slug="abuse"], [data-slug="desolate-wars"]) {
  --hub-goo-still: url(#hub-goo-spatter); --hub-goo-awake: hue-rotate(3deg) saturate(1.2) brightness(1.04); }
#portal-hero :is(#hero-portal, .hub-link):is([data-slug="dungeon"], [data-slug="wildy"], [data-slug="alice-in-cosmic-horror"], [data-slug="dark-fantasy"], [data-slug="dungeon-xyz"], [data-slug="grimoire"], [data-slug="wizards-of-the-white-mountains"]) {
  --hub-goo-still: url(#hub-goo-brew); --hub-goo-awake: hue-rotate(10deg) saturate(0.62) brightness(0.8); --hub-goo-rest: hue-rotate(10deg) saturate(0.62) brightness(0.82); }
.hub-goo-defs { position: absolute; left: 0; top: 0; width: 0; height: 0; overflow: hidden; pointer-events: none; }
:root:not(.gpu-unavailable) #portal-hero:not([data-goo="house"]) #hero-portal:not(.hub-still--empty)::after { filter: var(--hub-goo-still, none); }
:root:not(.gpu-unavailable) #portal-hero:not([data-goo="house"]) #hero-portal:not(.hub-still--empty) > .hub-still__art::before { filter: var(--hub-goo-awake, none); }
:root:not(.gpu-unavailable) #portal-hero:not([data-goo="house"]) .hub-link > .hub-still--small::after { filter: var(--hub-goo-rest, var(--hub-goo-awake, none)); }
@media (hover: hover) { :root:not(.gpu-unavailable) #portal-hero:not([data-goo="house"]) .hub-link:hover > .hub-still--small::after { filter: var(--hub-goo-awake, none); } }
:root:not(.gpu-unavailable) #portal-hero:not([data-goo="house"]) .hub-link:focus-visible > .hub-still--small::after, :root:not(.gpu-unavailable) #portal-hero:not([data-goo="house"]) .hub-link > .hub-still--small.is-awake::after { filter: var(--hub-goo-awake, none); }
/* /goo:stills */
