/* haso.lol portal shell. Design rationale, tokens and reviews: docs/brand/SITE.md. Mark: docs/brand/BRAND.md.
   One idea: the games are the colour; the shell is a calm sky that holds them.
   - Neutral ink + one accent (Haso Red, from the mark). Blue appears only as the system focus ring.
   - 8 pt grid. Radii 8 / 12 / 16 / 20, continuous corners where the browser can draw them.
   - Depth = one translucent header material + two soft shadows. No outlines, no pressed-in edges, no stripes.
   - Motion = springs, ≤ 500 ms, off under prefers-reduced-motion.
   Never: yellow/orange/beige casts, hard offset shadows, emoji/mascots, pill chips with dots, gradient blobs, sparkles. */
:root {
  /* colour: light */
  --ink: #0f2547; --muted: #5a6a86; --card: #fff; --accent: #ff3b5c; --ring: #1f8bff;
  --fill: rgba(15, 37, 71, .06); --fill2: rgba(15, 37, 71, .11); --hair: rgba(15, 37, 71, .1);
  --bg: var(--fill); --bg2: #e7eef8; --rule: var(--hair); /* names account.css reads */
  --material: rgba(255, 255, 255, .78);
  --sky1: #5ab8ff; --sky2: #aadcff; --sky3: #e9f5ff; --cloud: #fff; --hill1: #c9efdf; --hill2: #9fe0bd; --stars: 0;
  --tile-hair: rgba(15, 37, 71, .08); --stage: #0b1226;
  --sh1: 0 1px 2px rgba(15, 37, 71, .06), 0 6px 16px -6px rgba(15, 37, 71, .18);
  --sh2: 0 2px 4px rgba(15, 37, 71, .06), 0 20px 36px -14px rgba(15, 37, 71, .38);
  /* space (8 pt), radius, size */
  --s1: 8px; --s2: 16px; --s3: 24px; --s4: 32px; --s6: 48px; --s8: 64px;
  --gutter: 32px; --top: 56px; --hit: 44px;
  --r1: 8px; --r2: 12px; --r3: 16px; --r4: 20px;
  /* type */
  --display: "Bricolage Grotesque", ui-sans-serif, system-ui, sans-serif;
  --body: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  /* motion: damped springs as linear() (k 380 / c 24 ≈ 500 ms, slight overshoot; k 500 / c 40 ≈ 250 ms, none) */
  --spring: linear(0, .071, .235, .434, .628, .794, .92, 1.007, 1.059, 1.082, 1.085, 1.076, 1.061, 1.043, 1.027, 1.014, 1.004, .998, .994, .993, .993, .994, .995, .997, 1);
  --settle: linear(0, .024, .085, .166, .257, .35, .441, .526, .603, .671, .731, .782, .826, .862, .893, .917, .937, .953, .965, .975, .983, .988, .993, .996, 1);
  color-scheme: light;
}
@supports not (transition-timing-function: linear(0, 1)) { :root { --spring: cubic-bezier(.3, 1.35, .5, 1); --settle: cubic-bezier(.2, .8, .2, 1); } }
/* continuous corners where supported: superellipse corners need a slightly larger radius to read the same size */
@supports (corner-shape: superellipse(1.5)) {
  :root { --r2: 15px; --r3: 20px; --r4: 25px; }
  .tile, .tile img, .stage, .about, .btn, .iconbtn, .search, .bar > img, .splash img, .skel i, .info, .tags a, .exitfs { corner-shape: superellipse(1.5); }
}
/* colour: night. Same scene, navy sky, the cards step up in lightness instead of casting shadows. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink: #eef3ff; --muted: #9aa9c4; --card: #152040; --accent: #ff5a78; --ring: #5fb0ff;
    --fill: rgba(255, 255, 255, .08); --fill2: rgba(255, 255, 255, .14); --hair: rgba(255, 255, 255, .1); --bg2: #22305a;
    --material: rgba(10, 18, 40, .74);
    --sky1: #050b20; --sky2: #0b1a3e; --sky3: #142a58; --cloud: #142a57; --hill1: #13305a; --hill2: #0d2444; --stars: 1;
    --tile-hair: rgba(255, 255, 255, .08); --stage: #070d1e;
    --sh1: 0 1px 2px rgba(0, 0, 0, .3), 0 8px 20px -8px rgba(0, 0, 0, .6);
    --sh2: 0 2px 4px rgba(0, 0, 0, .3), 0 22px 40px -14px rgba(0, 0, 0, .8);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --ink: #eef3ff; --muted: #9aa9c4; --card: #152040; --accent: #ff5a78; --ring: #5fb0ff;
  --fill: rgba(255, 255, 255, .08); --fill2: rgba(255, 255, 255, .14); --hair: rgba(255, 255, 255, .1); --bg2: #22305a;
  --material: rgba(10, 18, 40, .74);
  --sky1: #050b20; --sky2: #0b1a3e; --sky3: #142a58; --cloud: #142a57; --hill1: #13305a; --hill2: #0d2444; --stars: 1;
  --tile-hair: rgba(255, 255, 255, .08); --stage: #070d1e;
  --sh1: 0 1px 2px rgba(0, 0, 0, .3), 0 8px 20px -8px rgba(0, 0, 0, .6);
  --sh2: 0 2px 4px rgba(0, 0, 0, .3), 0 22px 40px -14px rgba(0, 0, 0, .8);
  color-scheme: dark;
}
@media (max-width: 1199px) { :root { --gutter: 24px; } }
@media (max-width: 640px) { :root { --gutter: 16px; } }
@media (max-height: 520px) and (orientation: landscape) { :root { --top: 48px; } } /* phone on its side: every pixel to the game */

* { box-sizing: border-box; }
html, body { margin: 0; }
html { background: var(--sky3); }
body {
  font: 400 16px/1.5 var(--body); color: var(--ink);
  min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; overflow-x: clip;
  -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent;
}
main { flex: 1; width: 100%; padding: 0 var(--gutter) var(--s8); outline: none; }
a { color: inherit; text-underline-offset: 3px; text-decoration-thickness: 2px; }
button { font: inherit; color: inherit; cursor: pointer; }
:focus-visible { outline: 3px solid var(--ring); outline-offset: 2px; }
h1, h2 { font-family: var(--display); font-weight: 800; letter-spacing: -.02em; line-height: 1.1; }
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.skip { position: absolute; left: var(--s2); top: -60px; z-index: 99; background: var(--ink); color: var(--card); padding: var(--s1) var(--s2); border-radius: var(--r1); }
.skip:focus { top: var(--s1); }

/* page transitions: same-origin navigations cross-fade; the header holds still */
@view-transition { navigation: auto; }
.top { view-transition-name: top; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .18s; }

/* the scene: a calm sky behind everything. SVG masks filled with tokens, so night is just colours. */
.scene { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; background: linear-gradient(var(--sky1), var(--sky2) 45%, var(--sky3) 85%); }
.scene i { position: absolute; left: 0; display: block; }
.scene .stars {
  inset: 0 0 40% 0; opacity: calc(var(--stars) * .7);
  background:
    radial-gradient(circle at 22px 34px, #fff 1.2px, transparent 1.8px), radial-gradient(circle at 141px 18px, #fff .9px, transparent 1.5px),
    radial-gradient(circle at 96px 120px, #cfe3ff 1.4px, transparent 2px), radial-gradient(circle at 208px 84px, #fff .9px, transparent 1.5px),
    radial-gradient(circle at 60px 200px, #fff .9px, transparent 1.5px), radial-gradient(circle at 180px 230px, #cfe3ff 1.2px, transparent 1.8px);
  background-size: 260px 260px, 260px 260px, 370px 330px, 370px 330px, 290px 410px, 290px 410px;
  -webkit-mask-image: linear-gradient(#000, transparent); mask-image: linear-gradient(#000, transparent);
}
.scene .clouds {
  top: calc(var(--top) + 24px); left: -380px; height: 420px; width: calc(100% + 1780px); background: var(--cloud); opacity: .7;
  --m: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1400' height='420'%3E%3Cg%3E%3Ccircle cx='160' cy='110' r='38'/%3E%3Ccircle cx='212' cy='86' r='52'/%3E%3Ccircle cx='270' cy='112' r='34'/%3E%3Crect x='122' y='108' width='186' height='40' rx='20'/%3E%3Ccircle cx='652' cy='272' r='24'/%3E%3Ccircle cx='690' cy='254' r='36'/%3E%3Ccircle cx='728' cy='274' r='22'/%3E%3Crect x='628' y='270' width='122' height='26' rx='13'/%3E%3Ccircle cx='1072' cy='150' r='30'/%3E%3Ccircle cx='1118' cy='126' r='46'/%3E%3Ccircle cx='1166' cy='146' r='32'/%3E%3Ccircle cx='1200' cy='158' r='20'/%3E%3Crect x='1042' y='148' width='180' height='30' rx='15'/%3E%3C/g%3E%3C/svg%3E");
  -webkit-mask: var(--m) repeat-x 0 0 / 1400px 420px; mask: var(--m) repeat-x 0 0 / 1400px 420px;
}
.scene .hill { bottom: 0; right: 0; }
.scene .far {
  height: 200px; background: var(--hill1);
  --m: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1100' height='250'%3E%3Cpath d='M0 150C180 100 330 70 520 110S920 200 1100 150V250H0z'/%3E%3C/svg%3E");
  -webkit-mask: var(--m) repeat-x 0 100% / 880px 200px; mask: var(--m) repeat-x 0 100% / 880px 200px;
}
.scene .near {
  height: 136px; background: var(--hill2); left: -260px;
  --m: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1400' height='170'%3E%3Cpath d='M0 90C220 40 420 40 640 80S1180 140 1400 90V170H0z'/%3E%3Ccircle cx='300' cy='22' r='20'/%3E%3Crect x='297' y='30' width='6' height='26'/%3E%3Ccircle cx='334' cy='34' r='14'/%3E%3Crect x='331' y='40' width='6' height='18'/%3E%3Ccircle cx='980' cy='86' r='17'/%3E%3Crect x='977' y='94' width='6' height='26'/%3E%3C/svg%3E");
  -webkit-mask: var(--m) repeat-x 0 100% / 1120px 136px; mask: var(--m) repeat-x 0 100% / 1120px 136px;
}
@media (max-width: 640px) {
  .scene .far { height: 136px; -webkit-mask-size: 600px 136px; mask-size: 600px 136px; }
  .scene .near { height: 88px; -webkit-mask-size: 724px 88px; mask-size: 724px 88px; }
  .scene .clouds { -webkit-mask-size: 1000px 300px; mask-size: 1000px 300px; }
}
@media (prefers-reduced-motion: no-preference) {
  .scene .clouds { animation: drift 200s linear infinite; }
  @keyframes drift { to { transform: translateX(-1400px); } }
  @media (max-width: 640px) { .scene .clouds { animation-name: drift-s; } @keyframes drift-s { to { transform: translateX(-1000px); } } }
  @supports (animation-timeline: scroll()) {
    .scene .far { animation: sink linear both; animation-timeline: scroll(root); animation-range: 0 1400px; }
    .scene .near { animation: sink2 linear both; animation-timeline: scroll(root); animation-range: 0 1400px; }
    @keyframes sink { to { translate: 0 40px; } }
    @keyframes sink2 { to { translate: -120px 36px; } }
  }
}

/* header: one translucent bar. Mark + word on the left, search and Random on the right. Nothing else. */
.top {
  position: sticky; top: 0; z-index: 30; height: var(--top);
  display: flex; align-items: center; gap: var(--s1); padding: 0 var(--gutter);
  background: var(--material); box-shadow: 0 1px 0 var(--hair);
  -webkit-backdrop-filter: saturate(180%) blur(20px); backdrop-filter: saturate(180%) blur(20px);
}
.logo { display: flex; align-items: center; gap: 9px; height: var(--hit); text-decoration: none; flex-shrink: 0; border-radius: var(--r1); }
.logo .mk { width: 34px; height: 34px; flex: none; display: block; }
.logo .word { font-family: var(--display); font-weight: 800; font-size: 25px; font-variation-settings: "opsz" 36; letter-spacing: -.03em; line-height: 1; color: var(--ink); }
.logo .word b { font-weight: inherit; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) { /* BRAND.md: the mark laughs on hover, never rests tilted */
  .logo .mk { transition: rotate .5s var(--spring); }
  .logo:hover .mk { rotate: -8deg; }
}
.search {
  flex: 0 1 320px; margin-left: auto; display: flex; align-items: center; height: 40px;
  background: var(--fill); border-radius: var(--r2); transition: background-color .2s, box-shadow .2s;
}
.search:focus-within { background: var(--card); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 45%, transparent), var(--sh1); }
.search input { order: 2; flex: 1; min-width: 0; height: 100%; border: 0; background: none; outline: none; padding: 0 var(--s2) 0 0; font: inherit; font-size: 15px; color: var(--ink); }
.search input::placeholder { color: var(--muted); }
.search input::-webkit-search-cancel-button, .search input::-webkit-calendar-picker-indicator { display: none !important; }
.sbtn { order: 1; width: 40px; height: 100%; flex: none; padding: 0; border: 0; background: none; color: var(--muted); display: grid; place-items: center; border-radius: var(--r2); }
.sbtn svg { width: 17px; height: 17px; }

/* buttons: neutral fill by default; the accent fill is kept for the one primary action on a screen */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s1); height: 40px; padding: 0 var(--s2); flex-shrink: 0;
  border: 0; border-radius: var(--r2); background: var(--fill); color: var(--ink);
  font: 700 15px/1 var(--display); text-decoration: none; white-space: nowrap;
  transition: background-color .15s, transform .25s var(--settle);
}
.btn svg { width: 18px; height: 18px; flex: none; }
.btn:hover { background: var(--fill2); }
.btn:active, .iconbtn:active { transform: scale(.96); }
.btn.primary { background: var(--accent); color: #fff; }
.btn.primary:hover { background: color-mix(in oklab, var(--accent) 88%, #000); }
.rnd svg { color: var(--accent); }
.iconbtn {
  width: var(--hit); height: var(--hit); flex-shrink: 0; display: grid; place-items: center; padding: 0;
  border: 0; border-radius: var(--r2); background: none; color: var(--ink); transition: background-color .15s, transform .25s var(--settle);
}
.iconbtn:hover { background: var(--fill); }
.iconbtn svg { width: 22px; height: 22px; }
.iconbtn[aria-pressed="true"] { color: var(--accent); }
#fav[aria-pressed="true"] svg { fill: currentColor; }

/* category tabs: plain words on the sky; the current one is ink with a short red bar under it. No counts, no colours. */
.cats {
  display: flex; gap: 0; margin: var(--s1) calc(-1 * var(--gutter)) 0; padding: 0 calc(var(--gutter) - 12px);
  overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain;
}
.cats::-webkit-scrollbar { display: none; }
.cats.more-r { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 48px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 48px), transparent); }
.cats.more-l { -webkit-mask-image: linear-gradient(to right, transparent, #000 32px); mask-image: linear-gradient(to right, transparent, #000 32px); }
.cats.more-l.more-r { -webkit-mask-image: linear-gradient(to right, transparent, #000 32px, #000 calc(100% - 48px), transparent); mask-image: linear-gradient(to right, transparent, #000 32px, #000 calc(100% - 48px), transparent); }
.chip {
  position: relative; flex-shrink: 0; display: inline-flex; align-items: center; height: var(--hit); padding: 0 12px;
  font: 700 15px/1 var(--display); text-decoration: none; white-space: nowrap; color: color-mix(in srgb, var(--ink) 62%, transparent);
  border-radius: var(--r1); transition: color .15s;
}
.chip:hover { color: var(--ink); }
.chip small { display: none; }
.chip[aria-current="page"] { color: var(--ink); }
.chip[aria-current="page"]::after { content: ""; position: absolute; left: 12px; right: 12px; bottom: 4px; height: 3px; border-radius: 2px; background: var(--accent); }
.chip:focus-visible { outline-offset: -3px; }

/* section heads */
.sect { margin-top: var(--s6); content-visibility: auto; contain-intrinsic-size: auto 320px; }
.sh { display: flex; align-items: baseline; gap: var(--s2); margin: 0 0 var(--s2); }
.sh h1, .sh h2 { margin: 0; font-size: 22px; white-space: nowrap; }
.sh a { margin-left: auto; font: 600 15px/1 var(--body); color: var(--accent); text-decoration: none; padding: 14px 0; }
.sh a:hover { text-decoration: underline; }

/* tiles: the art is the tile. Rounded art, a hairline so pale art keeps its edge, the name underneath. */
.tile { position: relative; display: block; text-decoration: none; min-width: 0; border-radius: var(--r3); -webkit-touch-callout: none; }
.tile img {
  width: 100%; aspect-ratio: 1; height: auto; object-fit: cover; display: block; border-radius: var(--r3);
  background: color-mix(in oklab, var(--c, #8aa) 28%, var(--card)); box-shadow: var(--sh1); /* colour placeholder while the art loads */
}
.tile .name {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
  margin: var(--s1) 2px 0; font: 700 14px/1.25 var(--display); letter-spacing: -.01em; overflow-wrap: anywhere;
}
.tile .name .sub { color: var(--muted); font-weight: 600; }
.tile .new {
  position: absolute; top: var(--s1); left: var(--s1); z-index: 2; padding: 4px 6px; border-radius: 6px; background: var(--accent); color: #fff;
  font: 800 11px/1 var(--display); letter-spacing: .04em; text-transform: uppercase;
}
.tile.noimg::before {
  content: attr(data-t); display: flex; align-items: flex-end; aspect-ratio: 1; padding: 12px; border-radius: var(--r3);
  background: var(--c); color: #fff; font: 800 18px/1.1 var(--display); letter-spacing: -.02em; overflow: hidden; overflow-wrap: anywhere;
}
/* hover clip (app.js): laid over the art in the same box; fades in only once it is really playing */
.tile video {
  position: absolute; left: 0; top: 0; width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--r3); pointer-events: none;
  background: var(--fill); opacity: 0; transition: opacity .25s ease;
}
.tile video.on { opacity: 1; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .tile img, .tile video { transition: transform .5s var(--spring), box-shadow .3s, opacity .25s ease; }
  .tile:hover img, .tile:hover video { transform: translateY(-4px); box-shadow: var(--sh2); }
}

/* home + category: Poki-style mosaic. 1x1, l = 2x2, xl = 3x3 (app.js SIZE). Columns fill any width; tiles are square. */
.pg {
  --cell: 96px; --gap: var(--s1);
  display: grid; gap: var(--gap); margin-top: var(--s2); grid-auto-flow: row dense;
  grid-template-columns: repeat(auto-fill, minmax(var(--cell), 1fr));
}
@media (min-width: 641px) { .pg { --cell: 112px; --gap: var(--s2); } }
@media (min-width: 1200px) { .pg { --cell: 120px; } }
@media (min-width: 1600px) { .pg { --cell: 136px; } }

.pg .tile { aspect-ratio: 1; overflow: hidden; background: color-mix(in oklab, var(--c, #8aa) 28%, var(--card)); box-shadow: var(--sh1); isolation: isolate; } /* colour placeholder until the art decodes */
.pg .tile.l { grid-column: span 2; grid-row: span 2; border-radius: var(--r4); }
.pg .tile.xl { grid-column: span 3; grid-row: span 3; border-radius: var(--r4); }
/* phone: hero and big cards are 2x2 of 3 columns: 9 games above the fold instead of 5, and the 512 px art stays sharper */
@media (max-width: 640px) { .pg .tile.xl { grid-column: span 2; grid-row: span 2; } }
@media (max-width: 350px) { .logo .word b { display: none; } }
.pg .tile img, .pg .tile video { width: 100%; height: 100% !important; aspect-ratio: auto; border-radius: 0; box-shadow: none; transform: none !important; }
.pg .tile.noimg::before { height: 100%; aspect-ratio: auto; border-radius: 0; }
.pg .tile::after { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; box-shadow: inset 0 0 0 1px var(--tile-hair); pointer-events: none; }
/* the name rises over the art on hover / keyboard focus; it is always the link's accessible name */
.pg .tile .name {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1; margin: 0; padding: var(--s4) 12px 10px; display: block;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #fff; font-size: 14px;
  background: linear-gradient(rgba(5, 12, 32, 0), rgba(5, 12, 32, .78)); opacity: 0; transform: translateY(8px);
  transition: opacity .2s, transform .4s var(--settle);
}
.pg .tile .name .sub { color: rgba(255, 255, 255, .72); }
.pg .tile.l .name { font-size: 17px; padding: 40px var(--s2) 14px; }
.pg .tile.xl .name { font-size: 20px; padding: var(--s6) 20px var(--s2); }
.pg .tile:hover .name, .pg .tile:focus-visible .name { opacity: 1; transform: none; }
@media (hover: none) { .pg .tile.xl .name { opacity: 1; transform: none; } } /* touch has no hover: the hero cards always say what they are */
.tile .why { display: block; margin-top: 2px; font: 600 12px/1.3 var(--body); color: rgba(255, 255, 255, .8); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pg .tile:focus-visible { outline-offset: 3px; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .pg .tile { transition: transform .5s var(--spring), box-shadow .3s; }
  .pg .tile:hover { transform: scale(1.04); z-index: 2; box-shadow: var(--sh2); }
  .pg .tile.l:hover, .pg .tile.xl:hover { transform: scale(1.02); }
}
.pg .tile:active { transform: scale(.97); transition-duration: .15s; }
@media (max-width: 640px) {
  .pg .tile { border-radius: var(--r2); } .pg .tile.l, .pg .tile.xl { border-radius: var(--r3); }
  .pg .tile .new { top: 6px; left: 6px; padding: 3px 5px; font-size: 10px; }
}

/* category / search title: a large title above the grid, the count beside it */
.head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px var(--s2); margin: var(--s3) 0 0; }
.head h1 { margin: 0; font-size: clamp(28px, 4vw, 40px); overflow-wrap: anywhere; }
.head p { margin: 0; font-size: 15px; font-weight: 600; color: var(--muted); }
.head .mark { margin: 0; }
.foot { margin-top: var(--s6); }
.foot .intro { max-width: 68ch; margin: 0; font-size: 15px; color: var(--muted); }

.row {
  display: grid; grid-auto-flow: column; grid-auto-columns: 136px; gap: var(--s2); overflow-x: auto; scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--gutter); padding: var(--s1) var(--gutter) var(--s3); margin: calc(-1 * var(--s1)) calc(-1 * var(--gutter)) calc(-1 * var(--s2));
  scrollbar-width: none;
}
.row::-webkit-scrollbar { display: none; }
.row .tile { scroll-snap-align: start; }
.grid { display: grid; gap: var(--s3) var(--s2); grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); }

.launch { padding: var(--s6) 0; max-width: 560px; }
.launch .mark { margin: 0 0 var(--s3); }
.launch h1 { font-size: clamp(32px, 5vw, 44px); margin: 0 0 var(--s1); }
.launch p { font-size: 17px; color: var(--muted); margin: 0 0 var(--s3); }
.soon { display: none; }

/* skeleton (static HTML until games.json arrives): the same boxes the grid will fill, so nothing jumps */
.skel i { aspect-ratio: 1; border-radius: var(--r3); background: var(--card); opacity: .6; }
.skel i:first-child { background: var(--card) url(/mark.svg?v=3) center / 40% no-repeat; opacity: 1; }
.skel.grid { margin-top: var(--s2); gap: var(--s2); grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); }
.frame.skel { background: var(--stage) url(/mark.svg?v=3) center / 64px no-repeat; }
@media (prefers-reduced-motion: no-preference) { .skel i, .frame.skel { animation: pulse 1.2s ease-in-out infinite alternate; } }
.skel i:first-child { animation: none !important; }
@keyframes pulse { to { opacity: .35; } }

/* play page: the game is the only loud thing. Stage on the left, one quiet rail of similar games on the right. */
.play {
  --bar: 64px; --fh: max(320px, calc(100vh - var(--top) - var(--bar) - var(--s2) - var(--s3)));
  display: grid; gap: var(--s3); padding-top: var(--s2);
  grid-template-columns: minmax(0, 1fr) 296px; grid-template-areas: "stage r" "about r" "more more";
}
@supports (height: 100dvh) { .play { --fh: max(320px, calc(100dvh - var(--top) - var(--bar) - var(--s2) - var(--s3))); } }
.crumbs { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } /* for screen readers; the bar already says where you are */
.rail { display: grid; gap: var(--s3) var(--s2); align-content: start; }
.rail.l { display: none; }
.rail.r { grid-area: r; grid-template-columns: 1fr 1fr; }
.rail .name { font-size: 13px; }
.stage { grid-area: stage; position: relative; background: var(--card); border-radius: var(--r4); overflow: hidden; box-shadow: var(--sh1); }
.frame { position: relative; overflow: hidden; background: var(--stage); height: var(--fh); }
.frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; background: transparent; }
.splash { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s2); color: #fff; overflow: hidden; padding: var(--s2); text-align: center; }
.splash > * { position: relative; }
.splash img { width: min(36vw, 144px); height: auto; aspect-ratio: 1; border-radius: var(--r4); box-shadow: 0 2px 4px rgba(0, 0, 0, .2), 0 20px 40px -12px rgba(0, 0, 0, .55); }
.splash .txt { display: contents; }
.btn.big { height: 56px; padding: 0 var(--s4); gap: 10px; font-size: 19px; border-radius: var(--r3); }
.btn.big svg { width: 18px; height: 18px; }
.bar { display: flex; align-items: center; gap: 12px; height: var(--bar); padding: 0 var(--s1) 0 var(--s2); }
.bar > img { width: 40px; height: 40px; border-radius: 10px; flex-shrink: 0; box-shadow: inset 0 0 0 1px var(--tile-hair); }
.bar .t { flex: 1; min-width: 0; }
.bar h1 { font-size: 18px; margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; letter-spacing: -.015em; }
.bar .sub { display: flex; gap: 6px; white-space: nowrap; overflow: hidden; font-size: 13px; font-weight: 500; line-height: 1.3; }
.sub a { color: var(--muted); text-decoration: none; }
.sub a:hover { color: var(--ink); text-decoration: underline; }
.sub a + a::before { content: "·"; margin-right: 6px; }
.acts { display: flex; gap: 0; align-items: center; }
.btn.next { margin-left: var(--s1); }
.exitfs {
  position: fixed; top: max(var(--s1), env(safe-area-inset-top)); left: max(var(--s1), env(safe-area-inset-left)); z-index: 102;
  display: flex; align-items: center; gap: 4px; height: 36px; padding: 0 12px 0 var(--s1); border-radius: var(--r2); font: 600 13px/1 var(--body);
  border: 0; color: #fff; background: rgba(8, 14, 32, .6); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  animation: dim .4s 3s forwards;
}
.exitfs::after { content: ""; position: absolute; inset: -6px; }
.exitfs:hover, .exitfs:focus-visible { animation: none; opacity: 1; }
.exitfs[hidden] { display: none; }
.fstip { position: fixed; z-index: 102; top: max(var(--s1), env(safe-area-inset-top)); left: 50%; transform: translateX(-50%); max-width: calc(100vw - 140px); padding: 8px 12px; border-radius: var(--r2); font: 600 13px/1.3 var(--body); color: #fff; background: rgba(8, 14, 32, .72); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px); text-align: center; pointer-events: none; }
.exitfs svg { width: 16px; height: 16px; }
@keyframes dim { to { opacity: .35; } }
.about { grid-area: about; padding: var(--s3); background: var(--card); border-radius: var(--r4); box-shadow: var(--sh1); }
.about h2 { font-size: 20px; margin: 0 0 var(--s1); }
.about p { margin: 0 0 var(--s3); color: var(--muted); max-width: 68ch; font-size: 15px; line-height: 1.55; }
.tags { display: flex; flex-wrap: wrap; gap: var(--s1); }
.tags a { display: inline-flex; align-items: center; height: 36px; padding: 0 14px; border-radius: var(--r1); background: var(--fill); color: var(--ink); font: 700 14px/1 var(--display); text-decoration: none; }
.tags a:hover { background: var(--fill2); }
.more { grid-area: more; }
.near { grid-area: near; display: none; min-width: 0; }
.near .sect { margin-top: 0; }
/* game loading: the game's own art and name on its own colour, an indeterminate bar (no fake percentages) */
.loading {
  position: absolute; inset: 0; z-index: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s2);
  background: radial-gradient(circle at 50% 40%, color-mix(in oklab, var(--ga) 30%, #0b1226), color-mix(in oklab, var(--ga) 8%, #0b1226) 75%);
  color: rgba(255, 255, 255, .86); font: 600 15px/1.2 var(--body); transition: opacity .3s ease;
}
.loading.done { opacity: 0; pointer-events: none; }
.loading img { width: 96px; height: 96px; border-radius: var(--r4); box-shadow: 0 16px 32px -12px rgba(0, 0, 0, .6); }
.loading i { position: relative; width: 120px; height: 4px; border-radius: 2px; overflow: hidden; background: rgba(255, 255, 255, .18); }
.loading i::after { content: ""; position: absolute; inset: 0; width: 40%; border-radius: inherit; background: #fff; animation: sweep 1.1s var(--settle) infinite; }
@keyframes sweep { from { transform: translateX(-100%); } to { transform: translateX(250%); } }
@media (prefers-reduced-motion: reduce) { .loading i::after { width: 100%; opacity: .5; } }
/* before Play is tapped the splash is a poster, not the whole phone (play itself goes full viewport) */
.frame:has(.splash) { height: min(var(--fh), 80vw); min-height: 280px; }

/* per-game identity: app.js sets --ga (accent), --gb (field), --ga-ink from meta.json "theme" or the thumbnail.
   The game's colour lives inside the frame only: letterbox, splash, the Play button. The chrome stays neutral. */
.playpg { --ga: var(--accent); --gb: var(--fill); --ga-ink: #fff; }
.frame { background: color-mix(in oklab, var(--ga) 8%, var(--stage)); transition: background-color .4s; }
.splash { background: radial-gradient(circle at 50% 38%, color-mix(in oklab, var(--ga) 38%, #0b1226), color-mix(in oklab, var(--ga) 10%, #0b1226) 75%); }
.splash h2 { margin: 0; font-size: clamp(24px, 5vw, 32px); max-width: 16ch; text-wrap: balance; }
.splash .btn.big { background: var(--ga); color: var(--ga-ink); box-shadow: 0 8px 20px -8px rgba(0, 0, 0, .5); }
.splash .btn.big:hover { background: color-mix(in oklab, var(--ga) 86%, #fff); }

/* full-viewport play mode */
body.fs { overflow: hidden; }
body.fs .stage { position: fixed; inset: 0; z-index: 101; border-radius: 0; height: 100vh; height: 100dvh; box-shadow: none; }
body.fs .frame { height: 100%; min-height: 0; }
body.fs .bar { display: none; }
@media (prefers-reduced-motion: no-preference) {
  body.fs .stage { animation: grow .35s var(--settle); }
  @keyframes grow { from { opacity: .4; transform: scale(.97); } }
}

@media (max-width: 1099px) {
  .play { grid-template-columns: minmax(0, 1fr); grid-template-areas: "stage" "near" "about" "more"; --fh: max(300px, min(calc(100dvh - var(--top) - var(--bar) - var(--s2) - var(--s3)), 75vw)); }
  .rail { display: none !important; }
  .near { display: block; }
}
/* portrait window (narrow laptop browser, tablet upright): the game gets the full height, not a 75vw letterbox, so it lays out portrait */
@media (max-width: 1099px) and (orientation: portrait) { .play { --fh: max(300px, calc(100dvh - var(--top) - var(--bar) - var(--s2) - var(--s3))); } }
@media (max-width: 640px) {
  .top { gap: 4px; padding: 0 var(--s1) 0 var(--gutter); }
  .rnd span, .btn.next span, .hide-s { display: none; }
  .logo { gap: var(--s1); }
  .logo .mk { width: 30px; height: 30px; }
  .logo .word { font-size: 22px; }
  /* phone: search folds into a button-sized box and opens across the header while typing */
  .search { flex: 0 0 var(--hit); height: var(--hit); margin-left: auto; position: relative; background: none; }
  .search input { position: absolute; inset: 0; padding: 0 var(--s2) 0 var(--hit); color: transparent; cursor: pointer; }
  .search input::placeholder { color: transparent; }
  .sbtn { position: relative; z-index: 1; pointer-events: none; width: var(--hit); color: var(--ink); }
  .sbtn svg { width: 22px; height: 22px; }
  .search:focus-within { position: absolute; left: var(--s1); right: var(--s1); top: calc((var(--top) - var(--hit)) / 2); z-index: 3; background: var(--card); }
  .search:focus-within input { color: var(--ink); cursor: text; }
  .search:focus-within input::placeholder { color: var(--muted); }
  .search:focus-within .sbtn { color: var(--muted); }
  .rnd { width: var(--hit); height: var(--hit); padding: 0; background: none; }
  .rnd svg { width: 22px; height: 22px; }
  .acts .btn { width: var(--hit); height: var(--hit); padding: 0; }
  .sh h1, .sh h2 { font-size: 20px; }
  .grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s2) 12px; }
  .row { grid-auto-columns: 30%; gap: 12px; }
  .tile img, .tile video, .tile.noimg::before { border-radius: var(--r2); }
  .tile .name { font-size: 13px; }
  .play { margin: 0 calc(-1 * var(--gutter)); gap: var(--s3); padding-top: 0; }
  .stage { border-radius: 0; box-shadow: none; }
  .about, .more, .near { margin: 0 var(--gutter); }
  .about { padding: var(--s3) var(--s2); }
  .bar { padding: 0 var(--s1) 0 var(--s2); gap: var(--s1); }
  .bar h1 { font-size: 17px; }
}
/* phone on its side, before Play: poster and title side by side so the Play button is on screen */
@media (max-height: 520px) and (orientation: landscape) {
  .play { margin: 0 calc(-1 * var(--gutter)); padding-top: 0; gap: var(--s3); }
  .stage { border-radius: 0; box-shadow: none; }
  .about, .more, .near { margin: 0 var(--gutter); }
  .frame:has(.splash) { height: calc(100dvh - var(--top) - var(--bar)); min-height: 240px; }
  .splash { flex-direction: row; gap: var(--s3); }
  .splash img { width: min(36vh, 132px); }
  .splash .txt { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s2); text-align: left; }
  .logo .mk { width: 28px; height: 28px; }
  .logo .word { font-size: 21px; }
  .cats { margin-top: 0; }
  .pg { --cell: 96px; --gap: var(--s1); margin-top: var(--s1); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}

/* footer: one quiet line. The name's story, and the theme switch for people who don't want the system setting. */
footer {
  position: relative; width: 100%; margin-top: auto; padding: var(--s3) var(--gutter) max(var(--s3), env(safe-area-inset-bottom));
  background: var(--material); box-shadow: 0 -1px 0 var(--hair); color: var(--muted); font-size: 13px; line-height: 1.4;
  -webkit-backdrop-filter: saturate(180%) blur(20px); backdrop-filter: saturate(180%) blur(20px);
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1) var(--s3);
}
footer p { margin: 0; }
footer p:first-child { flex: 1 1 320px; }
footer i { font-style: normal; color: var(--ink); font-weight: 600; font-family: "Kohinoor Devanagari", "Noto Sans Devanagari", "Mukta", system-ui, sans-serif; }
footer .iconbtn { margin: -10px -10px -10px 0; color: var(--muted); }
footer .iconbtn:hover { color: var(--ink); }

/* plain text pages (privacy) */
.prose { max-width: 68ch; margin: var(--s6) 0; padding: var(--s4); background: var(--card); border-radius: var(--r4); box-shadow: var(--sh1); }
.prose h1 { margin: 0 0 var(--s2); font-size: clamp(32px, 5vw, 40px); }
.prose h2 { margin: var(--s4) 0 var(--s1); font-size: 20px; }
.prose p, .prose li { font-size: 16px; line-height: 1.6; color: var(--muted); }
.prose a { color: var(--accent); }
footer a { color: var(--ink); }
@media (max-width: 640px) { .prose { margin: var(--s3) 0; padding: var(--s3) var(--s2); } }
.prose b { color: var(--ink); }
.prose code { font-size: .9em; }
.prose .ctl { display: flex; flex-wrap: wrap; gap: var(--s1); margin-top: var(--s3); }
.prose .ctl .btn { height: var(--hit); }
.btn.tog[aria-pressed="true"] { background: var(--ink); color: var(--card); }

/* Halloween (seasonal, app.js sets html.hw from Oct 24 to Nov 1 local time; delete this block and that line after the season).
   Dusk sky, purple hills with pumpkins, a moon with bats; pumpkin-orange accent; the mark becomes a jack-o'-lantern in a witch hat.
   Colour and decoration only: no layout or tile geometry changes. */
html.hw {
  --accent: #d9480f; --hw2: #5b2bb5; --hw2-bg: rgba(124, 77, 255, .12);
  --sky1: #b39dfa; --sky2: #d9cdfb; --sky3: #fff0e6; --cloud: #fbf8ff; --hill1: #d7c6f4; --hill2: #b9a2ea;
  --hw-moon: #fffaf0; --hw-glow: rgba(255, 255, 255, .7); --hw-bat: rgba(52, 28, 102, .62); --hw-pk: #f76707; --hw-face: #3a1405; --hw-web: rgba(15, 37, 71, .2);
  --hw-hat: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 20'%3E%3Cpath fill='%233a1f6e' d='M6.5 16 13 3.2C14 1 16 .4 18 1.6l-1.6 1.6L21.5 16z'/%3E%3Cpath fill='%23ff8a1f' d='M8.8 11.4h10.9l1 2.6H7.5z'/%3E%3Cellipse fill='%233a1f6e' cx='14' cy='16.6' rx='13.4' ry='3'/%3E%3C/svg%3E");
  --hw-hat-d: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 20'%3E%3Cpath fill='%237b52d9' d='M6.5 16 13 3.2C14 1 16 .4 18 1.6l-1.6 1.6L21.5 16z'/%3E%3Cpath fill='%23ff8a1f' d='M8.8 11.4h10.9l1 2.6H7.5z'/%3E%3Cellipse fill='%237b52d9' cx='14' cy='16.6' rx='13.4' ry='3'/%3E%3C/svg%3E");
  --hw-pumpkin: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-24 -24 48 48'%3E%3Cpath fill='%23f76707' d='M0-16c-6 0-9 2-11 3-8-1-13 5-13 13s5 15 13 14c2 1 6 2 11 2s9-1 11-2c8 1 13-6 13-14s-5-14-13-13c-2-1-5-3-11-3z'/%3E%3Cpath fill='none' stroke='%23c2410c' stroke-width='2.4' d='M-9-12c-5 7-5 18 0 25M9-12c5 7 5 18 0 25'/%3E%3Cpath fill='%23537d2c' d='M-3-14l1-8h5l-1 8z'/%3E%3Cpath fill='%23ffd34d' d='M-11-3l5-6 4 6zM11-3l-5-6-4 6zM-12 4q12 11 24 0q-12 5-24 0z'/%3E%3C/svg%3E");
}
@media (prefers-color-scheme: dark) {
  html.hw:not([data-theme="light"]) {
    --accent: #f76707; --card: #1b1840; --bg2: #2a2557; --material: rgba(16, 10, 36, .74); --hw2: #cdb8ff; --hw2-bg: rgba(167, 139, 250, .16);
    --sky1: #0c0620; --sky2: #1b0f3d; --sky3: #2c1a56; --cloud: #2d1d58; --hill1: #221443; --hill2: #160c2e;
    --hw-moon: #ffe2a8; --hw-glow: rgba(255, 196, 110, .3); --hw-bat: #06030f; --hw-face: #2a0d02; --hw-web: rgba(255, 255, 255, .18); --hw-hat: var(--hw-hat-d);
  }
}
html.hw[data-theme="dark"] {
  --accent: #f76707; --card: #1b1840; --bg2: #2a2557; --material: rgba(16, 10, 36, .74); --hw2: #cdb8ff; --hw2-bg: rgba(167, 139, 250, .16);
  --sky1: #0c0620; --sky2: #1b0f3d; --sky3: #2c1a56; --cloud: #2d1d58; --hill1: #221443; --hill2: #160c2e;
  --hw-moon: #ffe2a8; --hw-glow: rgba(255, 196, 110, .3); --hw-bat: #06030f; --hw-face: #2a0d02; --hw-web: rgba(255, 255, 255, .18); --hw-hat: var(--hw-hat-d);
}
/* the scene: a moon behind the clouds and a few bats in front of it */
html.hw .scene::before, html.hw .scene::after { content: ""; position: absolute; pointer-events: none; }
html.hw .scene::before {
  top: calc(var(--top) + 34px); right: calc(4% + 56px); width: 100px; height: 100px; border-radius: 50%;
  background: radial-gradient(circle at 64% 36%, rgba(120, 90, 60, .09) 0 9%, transparent 10%), radial-gradient(circle at 36% 62%, rgba(120, 90, 60, .08) 0 13%, transparent 14%),
    radial-gradient(circle at 70% 72%, rgba(120, 90, 60, .07) 0 6%, transparent 7%), var(--hw-moon);
  box-shadow: 0 0 32px 6px var(--hw-glow), 0 0 120px 30px var(--hw-glow);
}
html.hw .scene::after {
  top: calc(var(--top) + 16px); right: 4%; width: 240px; height: 131px; background: var(--hw-bat);
  --m: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 220 120'%3E%3Cdefs%3E%3Cg id='b'%3E%3Cpath d='M18 8C14 4 8 3 2 5c3 2 4 4 4 6 2-1 4-1 5 1 1-1.5 4-1.5 6 0zM22 8c4-4 10-5 16-3-3 2-4 4-4 6-2-1-4-1-5 1-1-1.5-4-1.5-6 0z'/%3E%3Cellipse cx='20' cy='9.5' rx='2.6' ry='3.6'/%3E%3Cpath d='M18.2 6.5l.3-3.2 1.3 1.9h.4l1.3-1.9.3 3.2z'/%3E%3C/g%3E%3C/defs%3E%3Cuse href='%23b' transform='translate(96 46) scale(1.25)'/%3E%3Cuse href='%23b' transform='translate(14 22) rotate(-10) scale(.9)'/%3E%3Cuse href='%23b' transform='translate(172 18) rotate(8) scale(.6)'/%3E%3Cuse href='%23b' transform='translate(46 80) rotate(6) scale(.7)'/%3E%3C/svg%3E");
  -webkit-mask: var(--m) center / contain no-repeat; mask: var(--m) center / contain no-repeat;
}
/* narrower, the category tabs reach the moon: it drops below them so no tab ever sits on the bright disc.
   Phones have no free sky (titles run the full width), so no moon there. */
@media (max-width: 1099px) { html.hw .scene::before { top: calc(var(--top) + 124px); } html.hw .scene::after { top: calc(var(--top) + 106px); } }
@media (max-width: 640px) { html.hw .scene::before, html.hw .scene::after { display: none; } }
/* three pumpkins sit on the footer's top edge */
html.hw footer::before {
  content: ""; position: absolute; bottom: 100%; right: calc(var(--gutter) + 24px); width: 84px; height: 30px; pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 84 30'%3E%3Cdefs%3E%3Cg id='p'%3E%3Cpath fill='%23f76707' d='M0-16c-6 0-9 2-11 3-8-1-13 5-13 13s5 15 13 14c2 1 6 2 11 2s9-1 11-2c8 1 13-6 13-14s-5-14-13-13c-2-1-5-3-11-3z'/%3E%3Cpath fill='none' stroke='%23c2410c' stroke-width='2.4' d='M-9-12c-5 7-5 18 0 25M9-12c5 7 5 18 0 25'/%3E%3Cpath fill='%23537d2c' d='M-3-14l1-8h5l-1 8z'/%3E%3Cpath fill='%23ffd34d' d='M-11-3l5-6 4 6zM11-3l-5-6-4 6zM-12 4q12 11 24 0q-12 5-24 0z'/%3E%3C/g%3E%3C/defs%3E%3Cuse href='%23p' transform='translate(16 22) scale(.5)'/%3E%3Cuse href='%23p' transform='translate(68 23.9) scale(.38)'/%3E%3Cuse href='%23p' transform='translate(42 18.8) scale(.7)'/%3E%3C/svg%3E") center bottom / contain no-repeat;
}
/* header: the mark as a jack-o'-lantern under a witch hat, and a small greeting beside the name */
html.hw .logo { position: relative; }
html.hw .logo .mk path:first-child { fill: var(--hw-pk); }
html.hw .logo .mk path:last-child { fill: var(--hw-face); }
html.hw .logo::before {
  content: ""; position: absolute; left: -3px; top: -5px; width: 22px; height: 16px; rotate: -16deg; pointer-events: none;
  background: var(--hw-hat) center / contain no-repeat;
}
html.hw .logo::after {
  content: "Happy Halloween"; padding: 5px 8px 5px 25px; border-radius: 6px; white-space: nowrap; color: var(--hw2);
  background: var(--hw-pumpkin) 6px 50% / 15px no-repeat, var(--hw2-bg); font: 800 12px/1 var(--display); letter-spacing: 0;
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  html.hw .logo::before { transition: rotate .5s var(--spring); }
  html.hw .logo:hover::before { rotate: -26deg; }
}
@media (max-width: 640px) { html.hw .logo::before { top: -3px; left: -3px; } }
/* the header has no room for the words below 800 px (search, Random and Sign in): the pumpkin alone, and nothing below 360 px */
@media (max-width: 799px) { html.hw .logo::after { content: ""; width: 26px; height: 22px; padding: 0; background-position: 50% 50%; } }
@media (max-width: 359px) { html.hw .logo::after { display: none; } }
/* accents: the current tab's bar runs pumpkin to purple; hovered tiles glow */
html.hw .chip[aria-current="page"]::after { background: linear-gradient(90deg, var(--accent), var(--hw2)); }
@media (hover: hover) {
  html.hw .pg .tile:hover, html.hw :is(.row, .grid, .rail) .tile:hover img {
    box-shadow: var(--sh2), 0 0 0 2px color-mix(in srgb, var(--accent) 75%, transparent), 0 10px 32px -6px color-mix(in srgb, var(--accent) 55%, transparent);
  }
}
/* cobweb in the corner of the cards; the lost-page mark turns pumpkin and floats */
html.hw :is(.about, .prose) { position: relative; }
html.hw :is(.about, .prose)::after {
  content: ""; position: absolute; top: 0; right: 0; width: 76px; height: 76px; border-top-right-radius: var(--r4); pointer-events: none; background: var(--hw-web);
  --m: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 80'%3E%3Cpath fill='none' stroke='%23000' stroke-width='1.1' stroke-linecap='round' d='M80 0L0 0M80 0L6.1 30.6M80 0L23.4 56.6M80 0L49.4 73.9M80 0L80 80M62 0Q65.5 2.9 63.4 6.9Q67.7 8.2 67.3 12.7Q71.8 12.3 73.1 16.6Q77.1 14.5 80 18M44 0Q50.9 5.8 46.7 13.8Q55.3 16.5 54.5 25.5Q63.5 24.7 66.2 33.3Q74.2 29.1 80 36M24 0Q34.8 9 28.3 21.4Q41.6 25.6 40.4 39.6Q54.4 38.4 58.6 51.7Q71 45.2 80 56M2 0Q17 12.5 7.9 29.8Q26.6 35.7 24.8 55.2Q44.3 53.4 50.2 72.1Q67.5 63 80 78'/%3E%3C/svg%3E");
  -webkit-mask: var(--m) top right / 100% no-repeat; mask: var(--m) top right / 100% no-repeat;
}
@media (max-width: 640px) { html.hw :is(.about, .prose)::after { width: 52px; height: 52px; border-top-right-radius: var(--r3); } } /* text runs the full card width */
html.hw :is(.launch, .head) .mark { filter: hue-rotate(32deg) saturate(1.15); }
@media (prefers-reduced-motion: no-preference) {
  html.hw .scene::after { animation: hw-bob 3.2s ease-in-out infinite alternate; }
  html.hw .launch .mark { animation: hw-bob 2.6s ease-in-out infinite alternate; }
  @keyframes hw-bob { to { translate: 0 -6px; } }
}
