/* The game page frame (game-frame.js), the same around every catalog game: above the game's window a bar says what the
   game is — its icon, name, maker, upload day and how it is played, with its introduction and how to play folded under
   玩法 — and every other game runs down the column beside it; under the window its mods with Add mod, Remix and Create
   game (game-mods.js), then its comments and rankings (game-feed.js). Beside needs about 1040px of content: from 1360px,
   or from 1100px with the panel folded away (body.game-aside-beside); narrower, the other games come last, as a grid,
   and on a phone the bar follows the window as a card. Every game's viewport sizing subtracts --game-aside-space beside the rail and the
   panel, and on a desktop --site-header-h grows by the bar, so a board never runs under the aside or the bar. Surfaces are the
   homepage cards' body (#1f1f1f on the #181818 page); text 14px and up; motion 70/180ms. */
body.game-framed{--game-aside-w:300px;--game-frame-gap:24px;--game-frame-edge:24px;--game-aside-space:0px;--game-bar-h:56px;--frame-card:#1f1f1f;--frame-card-lit:#262626;--frame-key:#292929;--frame-key-lit:#303030;--frame-ink:#ededed;--frame-text:#cccccc;--frame-muted:#8f8f8f;--frame-pic:#252525;--frame-font:var(--site-nav-font,'Space Grotesk',system-ui,sans-serif);--frame-mono:var(--mono,'Geist Mono',ui-monospace,monospace);--frame-ease:cubic-bezier(.2,.8,.2,1)}
/* Pages on the lighter #212121 (Sheep Match, King's Game, Angry Uncle): the cards a step above the page, as #1f1f1f is above
   #181818 everywhere else. */
body.game-framed:is(.sheep-page,.king-page,.ojisan-page){--frame-card:#282828;--frame-card-lit:#2f2f2f;--frame-pic:#2e2e2e}

/* Beside: the body is a grid of two columns. The game's own shell stays where it is, at the top of the first; the feed
   and the mods stack under it in the same column, and the aside runs down the second beside all of them. The last row
   is flexible, so when the aside is the longer column its extra height gathers at the bottom, never between the
   sections. */
body.game-framed.game-aside-beside{display:grid;grid-template-columns:minmax(0,1fr) var(--game-aside-w);grid-template-rows:repeat(8,auto) 1fr;column-gap:var(--game-frame-gap);align-items:start;padding-right:var(--game-frame-edge);--game-aside-space:calc(var(--game-aside-w) + var(--game-frame-gap) + var(--game-frame-edge))}
body.game-framed.game-aside-beside>*{grid-column:1}
body.game-framed.game-aside-beside>[data-game-stage]{grid-column:1;grid-row:1;min-width:0;margin-block:0} /* a page's own margin:auto would centre it down the row */
body.game-framed.game-aside-beside>.game-frame-aside{grid-column:2;grid-row:1/-1;margin:calc(var(--site-bar-h,56px) + 16px) 0 24px} /* not sticky: the column is as long as the page */
body.game-framed.game-aside-beside>.game-frame-more{display:none} /* the column beside lists every other game */
/* On a desktop the bar sits above the game, in the band every game keeps under the site's bar (the shell's ::before,
   --site-header-h), which grows by the bar's height: 16px, the bar, 16px, then the game. Beside the aside it shares
   the game's grid row; narrower it is placed over the band. On a phone it follows the game, as a card. */
@media (min-width:761px) and (min-height:501px),(min-width:1001px){
 body.has-site-nav.site-nav-game.game-framed{--site-header-h:calc(var(--site-bar-h,56px) + 32px + var(--game-bar-h))}
 body.game-framed>.game-frame-bar{position:absolute;top:calc(var(--site-bar-h,56px) + 16px);left:calc(var(--site-nav-offset,0px) + 24px);right:24px;z-index:30;height:var(--game-bar-h);margin:0}
 body.game-framed.game-aside-beside>.game-frame-bar{grid-column:1;grid-row:1;align-self:start;position:relative;inset:auto;margin:calc(var(--site-bar-h,56px) + 16px) 0 0 24px}
}
/* Under the window, the mods and the feed take the window's edges: 24px from the panel, the column's full width. */
body.game-framed.game-aside-beside>:is(.game-mods,.game-feed){padding-left:24px;padding-right:0}
body.game-framed.game-aside-beside>:is(.game-mods,.game-feed) :is(.game-frame-wrap,.game-feed-grid){max-width:none}
body.game-framed #game-mods~.game-feed{padding-top:0}
/* The pixel-world games size their board and its row of numbers from the window themselves, so beside the aside their
   shell ends where the game ends and the comments and mods start right under it, not a screen down. (Every other game
   fills its shell, which stays one screen.) */
body.game-framed.game-aside-beside:is(.carrot-page,.quest-page,[data-game=flappy])>[data-game-stage]{height:auto}

/* The first screen stays the game. Pages that hold the document to one screen (mobile.css on phones, and the board
   and card tables everywhere) keep their shell at exactly that screen, and the document scrolls past it to the aside
   and the sections below — the rules game-feed.css applies once a feed arrives, here from the first frame (game-frame.js
   sets html[data-game-frame] before the page is drawn). Boards keep their touch-action, so a swipe on a board still
   plays the game; the page scrolls from everywhere else. */
html[data-game-frame]:has(body:is(.chess-page,.table-page,.cards-page)){height:auto;overflow-x:hidden;overflow-y:auto}
html[data-game-frame] body:is(.chess-page,.table-page,.cards-page){height:auto;min-height:100dvh;overflow:visible}
html[data-game-frame] body:is(.chess-page,.table-page,.cards-page)>.shell{height:100dvh;overflow:hidden}
html[data-game-frame]:has(body.uno-page){overflow-x:hidden;overflow-y:auto}
html[data-game-frame] body.uno-page{overflow:visible}
@media (max-width:760px),(max-width:1000px) and (max-height:500px){
 html[data-game-frame]:has(body.play-page){height:auto;overflow-x:hidden;overflow-y:auto}
 html[data-game-frame] body.play-page:not(.together-page){height:auto;min-height:100dvh;overflow:visible;padding-bottom:0}
 html[data-game-frame] body.play-page:not(.together-page)>:is(.shell,.page-shell){height:100dvh;overflow:hidden}
 html[data-game-frame] body.play-page .game-layout .game-actions{position:absolute}
 html[data-game-frame] body.relay-playing{height:auto;min-height:100dvh;overflow:visible}
 html[data-game-frame] body.relay-playing>.shell{height:100dvh;overflow:hidden}
}
html[data-game-frame] :is(.chess-board,.table-board,.card-arena,.uno-arena,.desktop-chroma-page #board){touch-action:pinch-zoom}

/* The aside: every other game, beside the window only (narrower, the grid at the bottom lists them). */
.game-frame-aside{display:flex;flex-direction:column;gap:16px;min-width:0;color:var(--frame-text);font:400 14px/20px var(--frame-font)}
body.game-framed:not(.game-aside-beside)>.game-frame-aside{display:none}
.game-frame-card{box-sizing:border-box;min-width:0;margin:0;padding:20px;border-radius:16px;background:var(--frame-card)}

/* The bar: the game's icon (its illustration framed as the search frames it), its name and one line of facts — who
   made it, the day it went up, how it is played — and 玩法, which folds out over the game like a menu. Narrower it is a
   card under the window, and 玩法 opens in place. */
.game-frame-bar{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:14px;box-sizing:border-box;min-width:0;color:var(--frame-text);font:400 14px/20px var(--frame-font)}
@media (max-width:760px),(max-width:1000px) and (max-height:500px){
 body.game-framed>.game-frame-bar{width:calc(100% - 2 * clamp(16px,4vw,40px));max-width:1120px;margin:24px auto;padding:16px 18px;border-radius:16px;background:var(--frame-card)}
 body.game-framed .game-frame-facts{flex-wrap:wrap;white-space:normal}
 /* The day and the fact wrap whole, onto a line of their own when they must, and a line never starts with a '·':
    every item leads with its separator, and the line starts 20px left of the facts, which clip it there. */
 body.game-framed .game-frame-when{display:flex;flex-wrap:wrap;flex-basis:calc(100% + 20px);min-width:0;margin-left:-20px}
 body.game-framed .game-frame-when::before{content:none}
 body.game-framed .game-frame-when>*{flex:none;max-width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
 body.game-framed .game-frame-when>:is(.game-frame-added,.game-frame-modes)::before{content:'·';display:inline-block;width:20px;margin:0;color:#5c5c5c;text-align:center}
 body.game-framed .game-frame-how{grid-column:1/-1;justify-self:stretch}
 body.game-framed .game-frame-how>summary{justify-content:space-between;width:100%;box-sizing:border-box}
 body.game-framed .game-frame-how-panel{margin-top:10px;padding:4px 2px 0;background:none;box-shadow:none}
}
.game-frame-icon{display:grid;grid-template:minmax(0,1fr)/minmax(0,1fr);place-items:center;width:48px;height:48px;border-radius:12px;background:var(--frame-pic);overflow:hidden}
.game-frame-icon>img{grid-area:1/1;display:block;width:auto;max-width:none;height:calc(44px * var(--icon-scale,1));transform:translate(var(--icon-x,0%),var(--icon-y,0%));pointer-events:none}
.game-frame-names{min-width:0}
.game-frame-title{margin:0;color:var(--frame-ink);font:600 18px/24px var(--frame-font);letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.game-frame-facts{display:flex;align-items:baseline;gap:0;min-width:0;margin:2px 0 0;color:var(--frame-muted);font:400 14px/20px var(--frame-font);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.game-frame-facts>*{flex:none}
.game-frame-label{margin-right:6px}
.game-frame-by{color:var(--frame-text)}
.game-frame-when::before,.game-frame-modes::before{content:'·';margin:0 8px;color:#5c5c5c}
.game-frame-how{position:relative;justify-self:end}
.game-frame-how>summary{display:flex;align-items:center;gap:6px;min-height:36px;padding:0 10px 0 14px;border-radius:10px;background:var(--frame-key);box-shadow:inset 0 1px 0 #ffffff12,0 2px 4px #00000059;color:var(--frame-ink);font:500 14px/20px var(--frame-font);white-space:nowrap;list-style:none;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color 180ms var(--frame-ease)}
.game-frame-how>summary::-webkit-details-marker{display:none}
.game-frame-how>summary>svg{flex:none;width:16px;height:16px;color:var(--frame-muted);transition:transform 180ms var(--frame-ease)}
.game-frame-how[open]>summary>svg{transform:rotate(180deg)}
.game-frame-how-panel{box-sizing:border-box;padding:16px 18px 6px;border-radius:14px;background:#262626;box-shadow:0 1px 2px #0000008c,0 8px 8px -6px #000000b3}
@media (min-width:761px) and (min-height:501px),(min-width:1001px){
 body.game-framed .game-frame-how-panel{position:absolute;top:calc(100% + 8px);right:0;width:min(400px,calc(100vw - 48px));max-height:min(520px,calc(100dvh - 180px));overflow:auto;overscroll-behavior:contain}
}
.game-frame-heading{margin:0 0 8px;color:var(--frame-ink);font:600 14px/20px var(--frame-font)}
.game-frame-blurb{margin:0 0 14px;color:var(--frame-text);font:400 14px/22px var(--frame-font)}
.game-frame-rules{display:grid;gap:8px;margin:0 0 12px;padding:0;list-style:none;counter-reset:frame-rule}
.game-frame-rules>li{display:grid;grid-template-columns:24px minmax(0,1fr);gap:8px;color:var(--frame-text);font:400 14px/22px var(--frame-font)}
.game-frame-rules>li::before{counter-increment:frame-rule;content:counter(frame-rule,decimal-leading-zero);color:var(--frame-muted);font:500 14px/22px var(--frame-mono)}
/* A game made in Workshop (community/game-page.js) has the same bar: its cover or its own pixel picture as the icon,
   its maker as a player (their avatar and profile) or Aspen Play's mark, and a like key beside 玩法. Until its data
   arrives the bar is a skeleton of the same height, so nothing moves when it fills. */
.game-frame-icon>img[data-kind=cover],.game-frame-icon>canvas{grid-area:1/1;display:block;width:100%;height:100%;object-fit:cover;transform:none}
.game-frame-bar[data-pending] .game-frame-title{color:var(--frame-muted)}
.game-frame-facts [hidden],.game-frame-modes:empty{display:none}
.game-frame-by[hidden]+.game-frame-when::before,.game-frame-added[hidden]+.game-frame-modes::before{content:none}
.game-frame-person{display:inline-flex;align-items:center;gap:6px;max-width:220px;color:var(--frame-text);text-decoration:none;vertical-align:top;transition:color 180ms var(--frame-ease)}
.game-frame-face{display:grid;place-items:center;flex:none;width:20px;height:20px;border-radius:50%;background:#303030;color:var(--frame-text);overflow:hidden}
.game-frame-face>svg{width:16px;height:16px}
.game-frame-face>img{display:block;width:100%;height:100%;object-fit:cover}
.game-frame-face[data-mark]{border-radius:0;background:none}
.game-frame-face>.game-frame-mark{display:block;width:20px;height:20px}
.game-frame-person-name{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.game-frame-bar[data-like]{grid-template-columns:auto minmax(0,1fr) auto auto}
.game-frame-like{display:inline-flex;align-items:center;gap:6px;min-height:36px;margin:0;padding:0 14px 0 12px;border:0;border-radius:10px;background:var(--frame-key);box-shadow:inset 0 1px 0 #ffffff12,0 2px 4px #00000059;color:var(--frame-ink);font:500 14px/20px var(--frame-font);white-space:nowrap;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:background-color 180ms var(--frame-ease),transform 180ms var(--frame-ease)}
.game-frame-like>svg{flex:none;width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linejoin:round}
.game-frame-like[aria-pressed=true]>svg{fill:currentColor}
.game-frame-like:disabled{color:var(--frame-muted);cursor:default}
.game-frame-like:active:not(:disabled){transform:translateY(1px);transition-duration:70ms}
@media (max-width:760px),(max-width:1000px) and (max-height:500px){
 body.game-framed .game-frame-bar[data-like]{grid-template-columns:auto minmax(0,1fr) auto}
}

/* Add mod, Remix, Create game: three keys on the Mods panel's title row, the site's own ways into Workshop; Add mod
   leads, lit. */
.game-frame-make{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;margin-left:auto}
.game-frame-action{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:40px;padding:0 16px 0 14px;box-sizing:border-box;border-radius:12px;background:var(--frame-key);box-shadow:inset 0 1px 0 #ffffff12,0 2px 4px #00000059;color:var(--frame-ink);font:500 14px/20px var(--frame-font);text-decoration:none;white-space:nowrap;touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:background-color 180ms var(--frame-ease),transform 180ms var(--frame-ease)}
.game-frame-action[data-action=mod]{background:#e6e6e6;box-shadow:inset 0 1px 0 #ffffff,0 2px 4px #00000059;color:#1d1d1d}
.game-frame-action>svg{flex:none;width:18px;height:18px}
.game-frame-action[hidden]{display:none}
.game-frame-action:active{transform:translateY(1px);transition-duration:70ms}

/* Other games: a picture, a name and how it is played; a game's screen when it has one, else its illustration. */
.game-frame-list{display:grid;gap:2px;margin:0 -6px;padding:0;list-style:none}
.game-frame-game{display:grid;grid-template-columns:72px minmax(0,1fr);grid-template-rows:auto auto;column-gap:12px;align-items:center;padding:6px;border-radius:12px;color:inherit;text-decoration:none;transition:background-color 180ms var(--frame-ease)}
.game-frame-game>.game-frame-pic{grid-row:1/3;width:72px;height:45px;border-radius:8px}
.game-frame-game>.game-frame-name{align-self:end;color:var(--frame-ink);font:500 14px/20px var(--frame-font);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.game-frame-game>.game-frame-meta{align-self:start;color:var(--frame-muted);font:400 14px/20px var(--frame-font);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.game-frame-pic{display:block;box-sizing:border-box;object-fit:cover;background:var(--frame-pic)}
.game-frame-pic[data-kind=art]{object-fit:contain;padding:4px}

/* Below the window: the comments and rankings (game-feed.js), the mods (game-mods.js) and, narrower, every other game. */
body.game-framed .game-feed{min-height:0;padding-bottom:40px}
.game-mods,.game-frame-more{box-sizing:border-box;width:100%;margin:0;padding:0 clamp(16px,4vw,40px) 40px;color:var(--frame-text);font:400 14px/20px var(--frame-font)}
.game-mods{padding-bottom:24px}
.game-frame-wrap{max-width:1120px;margin:0 auto}
.game-frame-more h2,.game-mods-head h2{margin:0;color:var(--frame-ink);font:500 18px/26px var(--frame-font);letter-spacing:-.01em}
.game-frame-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin:0 0 16px}
.game-frame-all{flex:none;color:var(--frame-muted);font:400 14px/20px var(--frame-font);text-decoration:none;transition:color 180ms var(--frame-ease)}
.game-frame-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:16px;margin:0;padding:0;list-style:none}
.game-frame-tile{display:flex;flex-direction:column;gap:2px;padding:6px 6px 8px;border-radius:16px;background:var(--frame-card);color:inherit;text-decoration:none;transition:background-color 180ms var(--frame-ease)}
.game-frame-tile>.game-frame-pic{width:100%;height:auto;aspect-ratio:16/10;margin:0 0 8px;border-radius:12px}
.game-frame-tile>.game-frame-name{padding:0 6px;color:var(--frame-ink);font:600 15px/22px var(--frame-font);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.game-frame-tile>.game-frame-meta{padding:0 6px;color:var(--frame-muted);font:400 14px/20px var(--frame-font)}

/* Mods: the plate the comments sit on (game-feed.css), a cover, a name, who made it and its likes. */
.game-mods-panel{padding:20px 20px 16px;border-radius:18px;background:#242424;box-shadow:inset 0 1px 0 #ffffff14,0 3px 7px #00000055}
.game-mods [hidden]{display:none!important}
.game-mods-head{display:flex;flex-wrap:wrap;align-items:center;gap:10px 12px;margin:0 0 16px}
.game-mods-count{color:var(--frame-muted);font:400 14px/20px var(--frame-font)}
.game-mods-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px;margin:0;padding:0;list-style:none}
.game-mods-card{display:flex;flex-direction:column;gap:2px;padding:6px 6px 10px;border-radius:14px;color:inherit;text-decoration:none;transition:background-color 180ms var(--frame-ease)}
.game-mods-art{position:relative;display:block;overflow:hidden;aspect-ratio:16/10;margin:0 0 8px;border-radius:10px;background:#1e1e1e}
.game-mods-art>:is(img,canvas){display:block;width:100%;height:100%;object-fit:cover}
.game-mods-name{display:-webkit-box;padding:0 4px;color:var(--frame-ink);font:600 15px/22px var(--frame-font);overflow:hidden;overflow-wrap:anywhere;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}
.game-mods-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;min-width:0;padding:0 4px;color:var(--frame-muted);font:400 14px/20px var(--frame-font)}
.game-mods-maker{display:flex;align-items:center;gap:6px;min-width:0}
.game-mods-maker>span:first-child{flex:none;width:20px;height:20px;border-radius:50%;overflow:hidden}
.game-mods-maker>span:last-child{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.game-mods-likes{flex:none}
.game-mods-art>.game-mods-likes{position:absolute;top:8px;left:8px;padding:0 8px;border-radius:999px;background:#303030;color:var(--frame-ink)} /* Aspen Play's own, on the cover's corner */
.game-mods-maker .game-mods-mark{display:block;width:20px;height:20px}
.game-mods-skeleton{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}
.game-mods-skeleton>i{display:block;aspect-ratio:16/12;border-radius:14px;background:#2a2a2a}
.game-mods-state{display:flex;flex-direction:column;align-items:flex-start;gap:12px;padding:4px 0}
.game-mods-state>p{margin:0;color:var(--frame-text);font:400 14px/22px var(--frame-font)}
.game-mods-button,.game-mods-more{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:40px;padding:0 16px;border:0;border-radius:12px;background:#2e2e2e;box-shadow:inset 0 1px 0 #ffffff12,0 2px 5px #00000059;color:var(--frame-ink);font:500 14px/20px var(--frame-font);text-decoration:none;white-space:nowrap;cursor:pointer;transition:background-color 180ms var(--frame-ease)}
.game-mods-more{margin:14px 0 0}
.game-mods-button:active,.game-mods-more:active{transform:translateY(1px);transition-duration:70ms}
@media(hover:hover){
 .game-frame-game:hover,.game-frame-tile:hover,.game-mods-card:hover{background:var(--frame-card-lit)}
 .game-frame-action:hover,.game-frame-how>summary:hover,.game-frame-like:hover:not(:disabled){background:var(--frame-key-lit)}
 a.game-frame-person:hover{color:var(--frame-ink)}
 .game-frame-action[data-action=mod]:hover{background:#f5f5f5}
 .game-frame-all:hover{color:var(--frame-ink)}
 .game-mods-button:hover,.game-mods-more:hover{background:#353535}
}
.game-frame-game:active,.game-frame-tile:active,.game-mods-card:active{background:var(--frame-card-lit);transition-duration:70ms}
.game-frame-bar :is(a,summary,button):focus-visible,.game-frame-aside a:focus-visible,.game-frame-more a:focus-visible,.game-mods :is(a,button):focus-visible{outline:2px solid #b5b5b5;outline-offset:2px}
@media(max-width:640px){
 .game-frame-grid,.game-mods-grid,.game-mods-skeleton{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
 .game-mods-panel{padding:16px 12px 12px;border-radius:16px}
 .game-frame-make{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));width:100%;margin:0}
 .game-frame-action{flex-direction:column;gap:4px;min-height:60px;padding:8px 4px}
 .game-frame-action>span{max-width:100%;overflow:hidden;text-overflow:ellipsis}
}
@media(prefers-reduced-motion:reduce){.game-frame-game,.game-frame-tile,.game-frame-all,.game-frame-action,.game-frame-how>summary,.game-frame-how>summary>svg,.game-frame-like,.game-frame-person,.game-mods-card,.game-mods-button,.game-mods-more{transition:none}.game-frame-action:active,.game-frame-like:active:not(:disabled),.game-mods-button:active,.game-mods-more:active{transform:none}}
@media(forced-colors:active){.game-frame-card,.game-frame-tile,.game-mods-panel,.game-mods-card,.game-frame-how-panel{border:1px solid CanvasText}.game-frame-action,.game-mods-button,.game-mods-more,.game-frame-how>summary,.game-frame-like{border:1px solid ButtonText}.game-frame-like[aria-pressed=true]>svg{fill:ButtonText}.game-frame-action[data-action=mod]{forced-color-adjust:none;background:ButtonText;color:ButtonFace}}
