/* game detail page: on top of style.css (.t3d product layout) */
.gd-back { display: inline-block; margin-bottom: 14px; font: 700 13px 'Fira Mono', ui-monospace, monospace; letter-spacing: .06em;
  color: #f3f1ec; opacity: .7; }
.gd-back:hover { opacity: 1; }
.gd-meta { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 10px; }
.gd-cat { font: 700 11px 'Fira Mono', ui-monospace, monospace; letter-spacing: .1em; text-transform: uppercase; color: #f3f1ec;
  padding: 5px 10px; border-radius: 999px; box-shadow: var(--ring); background: #ffffff08; }
.gd-cat::before { content: ""; display: inline-block; width: 8px; height: 8px; margin-right: 7px; vertical-align: -1px; border-radius: 1px;
  background: var(--chk) 0 0 / 4px 4px; }
.gd-code { font: 600 11px 'Fira Mono', ui-monospace, monospace; letter-spacing: .06em; opacity: .55; }
.gd-note { margin: -16px 0 20px; }
.gd-blurb { margin: 22px 0 0; opacity: .78; font-size: 15px; line-height: 1.55; }
.gd-dev { margin: 18px 0 0; }
.gd-toast { min-height: 0; margin: 0; font: 600 14px 'Mulish', system-ui, sans-serif; color: var(--green); opacity: 0; transition: opacity .3s; }
.gd-toast.on { opacity: 1; margin-top: 12px; }

.gd-addons { margin-top: 24px; padding-top: 16px; border-top: 1px solid #ffffff1c; }
.gd-addons h2 { font: 800 13px 'Fira Mono', ui-monospace, monospace; letter-spacing: .1em; text-transform: uppercase; margin: 0 0 10px; opacity: .7; }

/* art: the cover (3D cart over it when the store atlas has the game), else a flat cart */
.gd-art img.cover { width: 100%; display: block; }
.gd-cart { aspect-ratio: 57 / 65; max-width: 360px; margin: 0 auto; background: #161616; padding: 9% 9% 20%;
  border-radius: 14px; clip-path: polygon(0 0, 79% 0, 100% 32%, 100% 100%, 0 100%); box-shadow: var(--ring); position: relative; }
.gd-sticker { height: 100%; border-radius: 8px; background: #111; box-shadow: inset 0 0 0 3px #f3f1ec; display: grid; align-content: center;
  justify-items: center; gap: 2px; padding: 14px; position: relative; overflow: hidden; }
.gd-sticker i { position: absolute; left: 10px; right: 10px; top: 10px; height: 16px; background: var(--chk) 0 0 / 8px 8px; border-radius: 2px; }
.gd-sticker b { font: 900 22px 'Mulish', system-ui, sans-serif; letter-spacing: .06em; margin-top: 18px; }
.gd-sticker strong { font: 900 clamp(56px, 18vw, 96px)/1 'Mulish', system-ui, sans-serif; }
.gd-sticker span { font: 800 12px 'Fira Mono', ui-monospace, monospace; letter-spacing: .1em; opacity: .55; text-align: center; }
.gd-missing { display: grid; gap: 14px; justify-items: start; padding-block: 40px; }
#gd-tagline { white-space: pre; }
.t3d .product > .gd-art { background: none; padding: 0; box-shadow: none; }
.gd-cart { background: #262626; }
.gd-cart { padding: 26% 9% 23%; }

/* the toast: the Nimiq bottom overlay (12px gutters, all corners round, safe-area gap, centred on desktop) */
.gd-toast { position: fixed; z-index: 40; left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  max-width: 440px; margin: 0 auto !important; padding: 14px 16px; border-radius: 20px; background: #111; color: #f3f1ec;
  box-shadow: var(--ring), 0 10px 30px #000a; transform: translateY(12px); pointer-events: none; transition: opacity .3s, transform .3s; }
.gd-toast.on { transform: none; }
.gd-toast::before { content: ""; display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 10px; vertical-align: 1px; background: var(--green); }
@media (min-width: 912px) { .gd-toast { bottom: calc(24px + env(safe-area-inset-bottom, 0px)); } }

/* arriving from the vending machine: the machine's last frame and this page's first frame show the cart on
   the same pose, and the browser crossfades between them (t1 quick, t2 slow dissolve, t3 a straight cut) */
@view-transition { navigation: auto; }
html[data-vt="t1"]::view-transition-old(root), html[data-vt="t1"]::view-transition-new(root) { animation-duration: .35s; animation-timing-function: ease; }
html[data-vt="t2"]::view-transition-old(root), html[data-vt="t2"]::view-transition-new(root) { animation-duration: .9s; animation-timing-function: cubic-bezier(.4,0,.2,1); }
html[data-vt="t3"]::view-transition-group(root), html[data-vt="t3"]::view-transition-old(root), html[data-vt="t3"]::view-transition-new(root) { animation: none; }
html[data-arrive] header.top, html[data-arrive] footer, html[data-arrive] .product > div:not(.gd-art) { opacity: 0; }
html[data-arrive="land"] header.top, html[data-arrive="land"] footer, html[data-arrive="land"] .product > div:not(.gd-art) { opacity: 1; transition: opacity .6s .1s; }
/* a stage page (arrived from the machine): the cart is a full-screen 3D stage at the top, the header floats
   over it, and the title + Buy plate rises over its bottom edge. The stage never changes size, so the 3D
   canvas is never resized mid-flight. */
html[data-stagepage] header.top { position: absolute; top: 0; left: 0; right: 0; z-index: 5; background: transparent; }
html[data-stagepage] .hexfade, html[data-stagepage] .gd-back { display: none; }
html[data-stagepage] main.page { padding-top: 0; }
html[data-stagepage] .product { display: block; }
html[data-stagepage] .t3d .product > .gd-art, html[data-stagepage] .gd-art { width: 100vw; margin-left: calc(50% - 50vw); height: 100svh; position: relative; display: grid; place-items: center;
  background: #0b0b0b var(--poster, none) center / cover no-repeat; }
/* the poster is the stage until the 3D cart draws over it on the same pose; the flat cover stays out of the way */
html[data-stagepage] .gd-art img.cover { visibility: hidden; }
html[data-stagepage] .gd-art .cover3d { width: 100%; height: 100%; }
html[data-stagepage] .gd-art img.cover { width: 100%; height: 100%; object-fit: cover; border-radius: 0; box-shadow: none; }
html[data-stagepage] .gd-art .cart3d { border-radius: 0; }
html[data-stagepage] .product > div:not(.gd-art) { position: relative; z-index: 3; margin-top: calc(-1 * min(300px, 38svh)); box-shadow: var(--ring), 0 -12px 40px #000c; }
html[data-arrive] .product > div:not(.gd-art) { transform: translateY(60px); }
html[data-arrive="land"] .product > div:not(.gd-art) { transform: none; transition: opacity .6s .15s, transform .7s .15s cubic-bezier(.2,.8,.2,1); }
html[data-arrive="land"] /* the stage shows its poster from the very first frame, before the catalog answers (the crossfade lands on it) */
html[data-stagepage] #gd[hidden] { display: block !important; }

/* Extras: capsules in a sideways strip under the cart. Glass dome over the item's art, an ink base with the
   name and price; owned ones glow green and say Owned. A tap: the capsule presses, the dome lifts, the art pops. */
.gd-strip { list-style: none; margin: 0 -20px; padding: 6px 20px 14px; display: grid; grid-auto-flow: column; grid-auto-columns: 118px;
  gap: 12px; overflow-x: auto; scroll-snap-type: x proximity; scrollbar-width: none; }
.gd-strip::-webkit-scrollbar { display: none; }
.gd-strip li.empty { grid-column: 1 / -1; width: calc(100vw - 80px); max-width: 420px; padding: 12px; font-size: 14px; opacity: .6;
  border-radius: 10px; box-shadow: inset 0 0 0 1.5px #ffffff22; }
.gd-cap { scroll-snap-align: start; }
.gd-cap button { all: unset; box-sizing: border-box; cursor: pointer; display: grid; width: 118px; border-radius: 22px 22px 14px 14px;
  -webkit-tap-highlight-color: transparent; }
.gd-cap button:focus-visible { outline: 2px solid #f3f1ec; outline-offset: 3px; }
.gd-cap .dome { position: relative; height: 112px; border-radius: 59px 59px 10px 10px; overflow: hidden; display: grid; place-items: end center;
  background: radial-gradient(120% 90% at 50% 100%, #2a2a2a 0%, #151515 60%, #0e0e0e 100%);
  box-shadow: inset 0 0 0 1.5px #ffffff2e, inset 0 -18px 24px #0008; transition: transform .25s cubic-bezier(.2,.8,.2,1); }
.gd-cap .dome img { max-width: 86%; max-height: 92%; object-fit: contain; margin-bottom: 4px; filter: drop-shadow(0 6px 6px #000a);
  transition: transform .3s cubic-bezier(.2,1.4,.4,1); }
.gd-cap .dome .shine { position: absolute; inset: 8px 0 auto 16px; width: 26px; height: 54px; border-radius: 50%; transform: rotate(18deg);
  background: linear-gradient(180deg, #ffffff40, #ffffff00); pointer-events: none; }
.gd-cap .dome.noart::before { content: "?"; font: 900 40px 'Mulish', system-ui, sans-serif; opacity: .3; align-self: center; }
  background: radial-gradient(circle at 35% 35%, #f3f1ec, #b9b5ab 70%); box-shadow: 0 0 22px #f3f1ec33;
  font: 900 12px 'Fira Mono', ui-monospace, monospace; color: #111; padding-bottom: 6px; }
.gd-cap .base { display: grid; gap: 6px; padding: 9px 9px 10px; margin-top: -2px; border-radius: 0 0 14px 14px; background: #111;
  box-shadow: inset 0 0 0 1.5px #ffffff1c, 0 4px 0 #000; position: relative; }
.gd-cap .base::before { content: ""; position: absolute; left: 9px; right: 9px; top: 0; height: 4px; background: var(--chk) 0 0 / 4px 4px; opacity: .5; }
.gd-cap .base b { font: 800 13px/1.2 'Mulish', system-ui, sans-serif; min-height: 31px; display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; margin-top: 4px; }
.gd-cap .base em { font: 800 12px 'Fira Mono', ui-monospace, monospace; font-style: normal; justify-self: start; padding: 4px 9px; border-radius: 999px;
  background: var(--green); color: var(--green-ink); box-shadow: 0 2px 0 var(--green-lip); }
.gd-cap.owned .dome { box-shadow: inset 0 0 0 2px var(--green), 0 0 24px #21bca566, inset 0 -18px 24px #0008; }
.gd-cap.owned .base em { background: transparent; color: var(--green); box-shadow: inset 0 0 0 1.5px var(--green); }
.gd-cap.owned .base em::before { content: "\2713  "; }
/* the small vend */
.gd-cap.vending button { animation: gd-press .52s cubic-bezier(.3,.7,.3,1); }
.gd-cap.vending .dome { animation: gd-lift .52s cubic-bezier(.3,.7,.3,1); }
.gd-cap.vending .dome img { animation: gd-pop .52s cubic-bezier(.2,1.4,.4,1); }
@keyframes gd-press { 0% { transform: none; } 22% { transform: translateY(3px) scale(.96); } 60% { transform: translateY(-2px); } 100% { transform: none; } }
@keyframes gd-lift { 0%, 22% { transform: none; } 55% { transform: translateY(-7px); } 100% { transform: none; } }
@keyframes gd-pop { 0%, 30% { transform: none; } 62% { transform: scale(1.14) translateY(-4px); } 100% { transform: none; } }
@media (prefers-reduced-motion: reduce) { .gd-cap.vending button, .gd-cap.vending .dome, .gd-cap.vending .dome img { animation: none; } }
/* the info plate is a grid item: without min-width 0 the sideways strip widens it past the screen */
.product > div, .gd-addons { min-width: 0; }
.gd-toast:not(.on) { opacity: 0; visibility: hidden; }
/* the 3D rack is on (html[data-rack]): the strip is the screen-reader and keyboard path, hidden until focused */
html[data-rack] .gd-addons { position: relative; }
html[data-rack] .gd-addons h2 { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
html[data-rack] .gd-strip { position: absolute; left: 0; right: 0; clip-path: inset(50%); opacity: 0; }
html[data-rack] .gd-strip:focus-within { position: static; clip-path: none; opacity: 1; }

/* the sign is in the scene (html[data-sign]): the plate's title, price and button become its HTML twin, hidden until
   a keyboard reaches them; the line, the blurb and the extras list follow under the stage */
html[data-sign] .product > div:not(.gd-art) { margin-top: 0; }
html[data-sign] .gd-meta, html[data-sign] #gd-title, html[data-sign] #gd-price, html[data-sign] #gd-note {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; margin: 0; }
html[data-sign] #gd-actions { position: absolute; left: 20px; right: 20px; clip-path: inset(50%); opacity: 0; }
html[data-sign] #gd-actions:focus-within { position: static; clip-path: none; opacity: 1; }

/* the not-found room (lane 3's scene) takes this box; the text follows under it */
.gd-room { position: relative; height: min(56svh, 480px); width: 100%; border-radius: 14px; overflow: hidden; background: #000; }
