@ywkrlerche/richardwho 1.0.22 → 1.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/app.js +270 -82
  2. package/games.json +1 -1
  3. package/index.html +100 -48
  4. package/logos/1-on-1-soccer.webp +0 -0
  5. package/logos/1-on-1-tennis.webp +0 -0
  6. package/logos/10-minutes-till-dawn.webp +0 -0
  7. package/logos/1v1.lol.webp +0 -0
  8. package/logos/2048-cupcakes.webp +0 -0
  9. package/logos/2048.webp +0 -0
  10. package/logos/3D-flight-simulator.webp +0 -0
  11. package/logos/3d-free-kick.webp +0 -0
  12. package/logos/8-ball-classic.webp +0 -0
  13. package/logos/9007199254740992.webp +0 -0
  14. package/logos/Alpha_1.2.6.webp +0 -0
  15. package/logos/Indev.webp +0 -0
  16. package/logos/agar-io-lite.webp +0 -0
  17. package/logos/age-of-war-2.webp +0 -0
  18. package/logos/age-of-war.webp +0 -0
  19. package/logos/ages-of-conflict.webp +0 -0
  20. package/logos/among-us.webp +0 -0
  21. package/logos/angry-birds-space.webp +0 -0
  22. package/logos/angry-birds.webp +0 -0
  23. package/logos/awesome-tanks-2.webp +0 -0
  24. package/logos/awesome-tanks.webp +0 -0
  25. package/logos/bacon-may-die.webp +0 -0
  26. package/logos/bad-ice-cream-2.webp +0 -0
  27. package/logos/bad-ice-cream-3.webp +0 -0
  28. package/logos/bad-ice-cream.webp +0 -0
  29. package/logos/bad-parenting.webp +0 -0
  30. package/logos/bad-piggies.webp +0 -0
  31. package/logos/bank-robbery-2.webp +0 -0
  32. package/logos/bank-robbery-3.webp +0 -0
  33. package/logos/baseball-bros.webp +0 -0
  34. package/logos/basket-bros.webp +0 -0
  35. package/logos/basket-random.webp +0 -0
  36. package/logos/basketball-legends.webp +0 -0
  37. package/logos/basketball-stars.webp +0 -0
  38. package/logos/big-ice-tower-tiny-square.webp +0 -0
  39. package/logos/big-neon-tower-tiny-square.webp +0 -0
  40. package/logos/big-tower-tiny-square-2.webp +0 -0
  41. package/logos/big-tower-tiny-square.webp +0 -0
  42. package/logos/blocky-snakes.webp +0 -0
  43. package/logos/bloons-TD-2.webp +0 -0
  44. package/logos/bloons-TD.webp +0 -0
  45. package/logos/bloxorz.webp +0 -0
  46. package/logos/blumgi-racers.webp +0 -0
  47. package/logos/blumgi-rocket.webp +0 -0
  48. package/logos/bob-the-robber-2.webp +0 -0
  49. package/logos/bob-the-robber.webp +0 -0
  50. package/logos/bouncy-motors.webp +0 -0
  51. package/logos/boxing-random.webp +0 -0
  52. package/logos/breaking-the-bank.webp +0 -0
  53. package/logos/bubble-shooter.webp +0 -0
  54. package/logos/candy-crush.webp +0 -0
  55. package/logos/capybara-clicker.webp +0 -0
  56. package/logos/car-drawing.webp +0 -0
  57. package/logos/chaos-faction-2.webp +0 -0
  58. package/logos/chess.webp +0 -0
  59. package/logos/choppy-orc.webp +0 -0
  60. package/logos/circloO-2.webp +0 -0
  61. package/logos/circloO.webp +0 -0
  62. package/logos/clash-of-vikings.webp +0 -0
  63. package/logos/cleanup-io.webp +0 -0
  64. package/logos/cluster-rush.webp +0 -0
  65. package/logos/cookie-clicker.webp +0 -0
  66. package/logos/coreball.webp +0 -0
  67. package/logos/crazy-cars.webp +0 -0
  68. package/logos/crazy-cattle-3D.webp +0 -0
  69. package/logos/crazy-crash-landing.webp +0 -0
  70. package/logos/crazy-motorcycle.webp +0 -0
  71. package/logos/crossy-road.webp +0 -0
  72. package/logos/cut-the-rope-2.webp +0 -0
  73. package/logos/cut-the-rope-holiday-gift.webp +0 -0
  74. package/logos/cut-the-rope-time-travel.webp +0 -0
  75. package/logos/cut-the-rope.webp +0 -0
  76. package/logos/dadish-2.webp +0 -0
  77. package/logos/dadish-3.webp +0 -0
  78. package/logos/dadish.webp +0 -0
  79. package/logos/death-chase.webp +0 -0
  80. package/logos/death-run-3D.webp +0 -0
  81. package/logos/demolition-derby-crash-racing.webp +0 -0
  82. package/logos/doodle-jump.webp +0 -0
  83. package/logos/draw-climber.webp +0 -0
  84. package/logos/dreadhead-parkour.webp +0 -0
  85. package/logos/drift-boss.webp +0 -0
  86. package/logos/drift-hunters-pro.webp +0 -0
  87. package/logos/drive-mad.webp +0 -0
  88. package/logos/duck-life.webp +0 -0
  89. package/logos/ducklings-io.webp +0 -0
  90. package/logos/eagle-ride.webp +0 -0
  91. package/logos/earn-to-die-2.webp +0 -0
  92. package/logos/earn-to-die.webp +0 -0
  93. package/logos/eggy-car.webp +0 -0
  94. package/logos/elastic-face.webp +0 -0
  95. package/logos/escape-road-2.webp +0 -0
  96. package/logos/escape-road-3.webp +0 -0
  97. package/logos/escape-road.webp +0 -0
  98. package/logos/escaping-the-prison.webp +0 -0
  99. package/logos/eugenes-life.webp +0 -0
  100. package/logos/evil-glitch.webp +0 -0
  101. package/logos/fancy-pants-adventure-2.webp +0 -0
  102. package/logos/fancy-pants-adventure.webp +0 -0
  103. package/logos/fireblob.webp +0 -0
  104. package/logos/fireboy-and-watergirl.webp +0 -0
  105. package/logos/flappy-bird.webp +0 -0
  106. package/logos/fleeing-the-complex.webp +0 -0
  107. package/logos/flood-runner-2.webp +0 -0
  108. package/logos/flood-runner-3.webp +0 -0
  109. package/logos/flood-runner-4.webp +0 -0
  110. package/logos/fnaf-2.webp +0 -0
  111. package/logos/fnaf-3.webp +0 -0
  112. package/logos/fnaf.webp +0 -0
  113. package/logos/football-bros.webp +0 -0
  114. package/logos/football-legends.webp +0 -0
  115. package/logos/friday-night-funkin.webp +0 -0
  116. package/logos/fruit-ninja.webp +0 -0
  117. package/logos/funny-battle.webp +0 -0
  118. package/logos/funny-mad-racing.webp +0 -0
  119. package/logos/funny-shooter-2.webp +0 -0
  120. package/logos/geometry-dash-lite.webp +0 -0
  121. package/logos/geometry-dash.webp +0 -0
  122. package/logos/geometry-vibes.webp +0 -0
  123. package/logos/get-on-top.webp +0 -0
  124. package/logos/getaway-shootout.webp +0 -0
  125. package/logos/gladi-hoppers.webp +0 -0
  126. package/logos/google-baseball.webp +0 -0
  127. package/logos/google-dino.webp +0 -0
  128. package/logos/granny.webp +0 -0
  129. package/logos/guess-their-answer.webp +0 -0
  130. package/logos/happy-wheels.webp +0 -0
  131. package/logos/helix-jump.webp +0 -0
  132. package/logos/highway-traffic.webp +0 -0
  133. package/logos/hill-climb-racing-lite.webp +0 -0
  134. package/logos/hole-io.webp +0 -0
  135. package/logos/house-of-hazards.webp +0 -0
  136. package/logos/hover-racer-drive.webp +0 -0
  137. package/logos/ice-dodo.webp +0 -0
  138. package/logos/idle-breakout.webp +0 -0
  139. package/logos/idle-dice.webp +0 -0
  140. package/logos/infiltrating-the-airship.webp +0 -0
  141. package/logos/iron-snout.webp +0 -0
  142. package/logos/jacksmith.webp +0 -0
  143. package/logos/jetpack-joyride.webp +0 -0
  144. package/logos/johnny-trigger.webp +0 -0
  145. package/logos/jumping-shell.webp +0 -0
  146. package/logos/karate-bros.webp +0 -0
  147. package/logos/kart-bros.webp +0 -0
  148. package/logos/kittytoy.webp +0 -0
  149. package/logos/learn-to-fly-2.webp +0 -0
  150. package/logos/learn-to-fly-3.webp +0 -0
  151. package/logos/learn-to-fly.webp +0 -0
  152. package/logos/level-devil.webp +0 -0
  153. package/logos/little-alchemy-2.webp +0 -0
  154. package/logos/madalin-stunt-cars-2.webp +0 -0
  155. package/logos/madness-project-nexus.webp +0 -0
  156. package/logos/melon-playground.webp +0 -0
  157. package/logos/merge-round-racers.webp +0 -0
  158. package/logos/minesweeper.webp +0 -0
  159. package/logos/monkey-mart.webp +0 -0
  160. package/logos/monster-tracks.webp +0 -0
  161. package/logos/motherload.webp +0 -0
  162. package/logos/moto-x3m-2.webp +0 -0
  163. package/logos/moto-x3m-3.webp +0 -0
  164. package/logos/moto-x3m-pool-party.webp +0 -0
  165. package/logos/moto-x3m-spooky-land.webp +0 -0
  166. package/logos/moto-x3m-winter.webp +0 -0
  167. package/logos/moto-x3m.webp +0 -0
  168. package/logos/murder.webp +0 -0
  169. package/logos/noob-miner.webp +0 -0
  170. package/logos/openTTD.webp +0 -0
  171. package/logos/opposite-day.webp +0 -0
  172. package/logos/ovo.webp +0 -0
  173. package/logos/pac-man.webp +0 -0
  174. package/logos/papas-bakeria.webp +0 -0
  175. package/logos/papas-burgeria.webp +0 -0
  176. package/logos/papas-cheeseria.webp +0 -0
  177. package/logos/papas-cupcakeria.webp +0 -0
  178. package/logos/papas-donuteria.webp +0 -0
  179. package/logos/papas-freezeria.webp +0 -0
  180. package/logos/papas-pancakeria.webp +0 -0
  181. package/logos/papas-pastaria.webp +0 -0
  182. package/logos/papas-pizzeria.webp +0 -0
  183. package/logos/papas-scooperia.webp +0 -0
  184. package/logos/papas-sushiria.webp +0 -0
  185. package/logos/papas-taco-mia.webp +0 -0
  186. package/logos/papas-wingeria.webp +0 -0
  187. package/logos/paper-io-2.webp +0 -0
  188. package/logos/parking-fury-2.webp +0 -0
  189. package/logos/picos-school.webp +0 -0
  190. package/logos/ping-pong-chaos.webp +0 -0
  191. package/logos/pixel-speedrun.webp +0 -0
  192. package/logos/plants-vs-zombies.webp +0 -0
  193. package/logos/plonky.webp +0 -0
  194. package/logos/polytrack.webp +0 -0
  195. package/logos/poor-bunny.webp +0 -0
  196. package/logos/pou.webp +0 -0
  197. package/logos/ragdoll-archers.webp +0 -0
  198. package/logos/ragdoll-hit.webp +0 -0
  199. package/logos/ragdoll-soccer.webp +0 -0
  200. package/logos/red-ball-4-vol-1.webp +0 -0
  201. package/logos/red-ball-4-vol-2.webp +0 -0
  202. package/logos/red-ball-4-vol-3.webp +0 -0
  203. package/logos/retro-bowl-college.webp +0 -0
  204. package/logos/retro-bowl.webp +0 -0
  205. package/logos/retro-highway.webp +0 -0
  206. package/logos/retro-ping-pong.webp +0 -0
  207. package/logos/riddle-school-2.webp +0 -0
  208. package/logos/riddle-school-3.webp +0 -0
  209. package/logos/riddle-school-4.webp +0 -0
  210. package/logos/riddle-school-5.webp +0 -0
  211. package/logos/riddle-school.webp +0 -0
  212. package/logos/riddle-transfer.webp +0 -0
  213. package/logos/rocket-soccer-derby.webp +0 -0
  214. package/logos/rooftop-run.webp +0 -0
  215. package/logos/rooftop-snipers-2.webp +0 -0
  216. package/logos/rooftop-snipers.webp +0 -0
  217. package/logos/run-2.webp +0 -0
  218. package/logos/run-3.webp +0 -0
  219. package/logos/run.webp +0 -0
  220. package/logos/sandbox-city.webp +0 -0
  221. package/logos/short-life.webp +0 -0
  222. package/logos/slope-2-player.webp +0 -0
  223. package/logos/slope-3.webp +0 -0
  224. package/logos/slope.webp +0 -0
  225. package/logos/snail-bob-2.webp +0 -0
  226. package/logos/snail-bob-3.webp +0 -0
  227. package/logos/snail-bob-4.webp +0 -0
  228. package/logos/snail-bob-5.webp +0 -0
  229. package/logos/snail-bob-6.webp +0 -0
  230. package/logos/snail-bob-7.webp +0 -0
  231. package/logos/snail-bob-8.webp +0 -0
  232. package/logos/snail-bob.webp +0 -0
  233. package/logos/snow-rider.webp +0 -0
  234. package/logos/snow-road.webp +0 -0
  235. package/logos/snowball-io.webp +0 -0
  236. package/logos/soccer-bros.webp +0 -0
  237. package/logos/soccer-random.webp +0 -0
  238. package/logos/space-is-key-2.webp +0 -0
  239. package/logos/space-is-key.webp +0 -0
  240. package/logos/space-waves.webp +0 -0
  241. package/logos/spacebar-clicker.webp +0 -0
  242. package/logos/speed-stars.webp +0 -0
  243. package/logos/sprunki.webp +0 -0
  244. package/logos/stack.webp +0 -0
  245. package/logos/stacktris.webp +0 -0
  246. package/logos/state-io.webp +0 -0
  247. package/logos/stealing-the-diamond.webp +0 -0
  248. package/logos/stick-archers-battle.webp +0 -0
  249. package/logos/stick-fighter.webp +0 -0
  250. package/logos/stick-merge.webp +0 -0
  251. package/logos/stickman-hook.webp +0 -0
  252. package/logos/subway-surfers-beijing.webp +0 -0
  253. package/logos/subway-surfers-havana.webp +0 -0
  254. package/logos/subway-surfers-san-francisco.webp +0 -0
  255. package/logos/super-bike-the-champion.webp +0 -0
  256. package/logos/super-liquid-soccer.webp +0 -0
  257. package/logos/super-star-car.webp +0 -0
  258. package/logos/table-tennis-world-tour.webp +0 -0
  259. package/logos/tag.webp +0 -0
  260. package/logos/tanuki-sunset.webp +0 -0
  261. package/logos/tap-road.webp +0 -0
  262. package/logos/temple-of-boom.webp +0 -0
  263. package/logos/temple-run-2.webp +0 -0
  264. package/logos/territorial-io.webp +0 -0
  265. package/logos/tetrominoes.webp +0 -0
  266. package/logos/the-impossible-quiz-2.webp +0 -0
  267. package/logos/the-impossible-quiz.webp +0 -0
  268. package/logos/they-are-coming.webp +0 -0
  269. package/logos/this-is-the-only-level-too.webp +0 -0
  270. package/logos/this-is-the-only-level.webp +0 -0
  271. package/logos/time-shooter-2.webp +0 -0
  272. package/logos/time-shooter-3.webp +0 -0
  273. package/logos/tiny-fishing.webp +0 -0
  274. package/logos/trap-the-cat.webp +0 -0
  275. package/logos/trivia-crack.webp +0 -0
  276. package/logos/tube-jumpers.webp +0 -0
  277. package/logos/tunnel-rush.webp +0 -0
  278. package/logos/unicycle-hero.webp +0 -0
  279. package/logos/vex-4.webp +0 -0
  280. package/logos/vex-5.webp +0 -0
  281. package/logos/vex-x3m-2.webp +0 -0
  282. package/logos/vex-x3m.webp +0 -0
  283. package/logos/volley-random.webp +0 -0
  284. package/logos/war-the-knights.webp +0 -0
  285. package/logos/we-become-what-we-behold.webp +0 -0
  286. package/logos/wheelie-bike.webp +0 -0
  287. package/logos/wheely-2.webp +0 -0
  288. package/logos/wheely-3.webp +0 -0
  289. package/logos/wheely-4.webp +0 -0
  290. package/logos/wheely-5.webp +0 -0
  291. package/logos/wheely-6.webp +0 -0
  292. package/logos/wheely-7.webp +0 -0
  293. package/logos/wheely.webp +0 -0
  294. package/logos/wordle-unlimited.webp +0 -0
  295. package/logos/worlds-hardest-game-2.webp +0 -0
  296. package/logos/worlds-hardest-game.webp +0 -0
  297. package/logos/wrestle-bros.webp +0 -0
  298. package/logos/yohoho-io.webp +0 -0
  299. package/logos/zombie-rush.webp +0 -0
  300. package/package.json +4 -3
  301. package/style.css +194 -160
package/style.css CHANGED
@@ -1,190 +1,224 @@
1
+ /* richardwho: dark, minimal, sidebar layout */
1
2
  :root {
2
- --bg: #0b0d14;
3
- --bg-2: #121522;
4
- --card: #171a2a;
5
- --card-hover: #1e2236;
6
- --line: #262a40;
7
- --text: #eef0fa;
8
- --muted: #8b90ab;
9
- --accent: #7c5cff;
10
- --accent-2: #22d3ee;
11
- --danger: #ff4d6d;
12
- --island: #000;
13
- --island-text: #fff;
14
- --shadow: 0 10px 30px rgba(0, 0, 0, .35);
15
- --radius: 16px;
3
+ --bg: #000000;
4
+ --panel: #0a0a0c;
5
+ --tile: #111114;
6
+ --line: rgba(255, 255, 255, .09);
7
+ --line-2: rgba(255, 255, 255, .16);
8
+ --text: #f5f5f7;
9
+ --muted: rgba(255, 255, 255, .55);
10
+ --soft: rgba(255, 255, 255, .06);
11
+ --soft-2: rgba(255, 255, 255, .1);
12
+ --accent: #3b82f6;
13
+ --danger: #ef4444;
14
+ --glow-blue: rgba(30, 64, 175, .55);
15
+ --glow-orange: rgba(194, 92, 30, .35);
16
+ --rail-w: 58px;
17
+ --per-row: 6;
18
+ --font: "Inter", "Segoe UI Variable Display", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif;
16
19
  color-scheme: dark;
17
20
  }
18
21
  [data-theme="light"] {
19
- --bg: #f4f5fb;
20
- --bg-2: #ffffff;
21
- --card: #ffffff;
22
- --card-hover: #f0f1fa;
23
- --line: #e2e4f0;
24
- --text: #14162b;
25
- --muted: #646a88;
26
- --accent: #6a46ff;
27
- --accent-2: #0891b2;
28
- --island: #14162b;
29
- --shadow: 0 8px 24px rgba(20, 22, 43, .08);
22
+ --bg: #f6f6f8;
23
+ --panel: #ffffff;
24
+ --tile: #e9e9ee;
25
+ --line: rgba(0, 0, 0, .1);
26
+ --line-2: rgba(0, 0, 0, .18);
27
+ --text: #0b0b0f;
28
+ --muted: rgba(0, 0, 0, .55);
29
+ --soft: rgba(0, 0, 0, .05);
30
+ --soft-2: rgba(0, 0, 0, .09);
31
+ --glow-blue: rgba(59, 130, 246, .28);
32
+ --glow-orange: rgba(249, 115, 22, .2);
30
33
  color-scheme: light;
31
34
  }
32
35
 
33
36
  * { box-sizing: border-box; }
34
37
  html, body { margin: 0; }
35
38
  body {
36
- background:
37
- radial-gradient(1200px 500px at 10% -10%, color-mix(in srgb, var(--accent) 18%, transparent), transparent 60%),
38
- radial-gradient(900px 400px at 100% 0%, color-mix(in srgb, var(--accent-2) 12%, transparent), transparent 60%),
39
- var(--bg);
40
- background-attachment: fixed;
41
- color: var(--text);
42
- font: 15px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
43
- min-height: 100vh;
44
- display: flex;
45
- flex-direction: column;
46
- }
47
- button { font: inherit; color: inherit; cursor: pointer; }
48
- kbd {
49
- font: 12px ui-monospace, Consolas, monospace;
50
- padding: 1px 6px; border-radius: 6px;
51
- border: 1px solid var(--line); background: var(--bg-2); color: var(--muted);
39
+ min-height: 100vh; background: var(--bg); color: var(--text);
40
+ font: 15px/1.45 var(--font); overflow-x: hidden;
52
41
  }
42
+ button, select, input { font: inherit; color: inherit; }
43
+ button { cursor: pointer; }
53
44
  [hidden] { display: none !important; }
45
+ kbd { font: 600 11px ui-monospace, Consolas, monospace; padding: 1px 6px; border-radius: 5px; border: 1px solid var(--line); background: var(--soft); }
46
+ :focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }
54
47
 
55
- /* ---------- Top bar ---------- */
56
- .topbar {
57
- position: sticky; top: 0; z-index: 10;
58
- display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 12px;
59
- padding: 12px clamp(16px, 3vw, 32px);
60
- background: color-mix(in srgb, var(--bg) 75%, transparent);
61
- backdrop-filter: blur(14px);
62
- border-bottom: 1px solid var(--line);
63
- }
64
- .brand { display: flex; align-items: center; gap: 10px; color: var(--text); text-decoration: none; min-width: 0; }
65
- .brand-mark {
66
- flex: none; width: 34px; height: 34px; border-radius: 10px;
67
- display: grid; place-items: center; font-weight: 800; color: #fff;
68
- background: linear-gradient(135deg, var(--accent), var(--accent-2));
69
- box-shadow: 0 0 18px color-mix(in srgb, var(--accent) 50%, transparent);
48
+ /* ---------- Aurora glow ---------- */
49
+ .aurora { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
50
+ .aurora span { position: absolute; border-radius: 50%; filter: blur(90px); }
51
+ .aurora .a1 { width: 70vw; height: 26vh; left: 22vw; top: 8vh; background: var(--glow-blue); transform: rotate(-12deg); animation: drift 18s ease-in-out infinite alternate; }
52
+ .aurora .a2 { width: 34vw; height: 20vh; right: -6vw; top: -6vh; background: var(--glow-orange); animation: drift 22s ease-in-out infinite alternate-reverse; }
53
+ .aurora .a3 { width: 40vw; height: 18vh; left: 8vw; top: 26vh; background: color-mix(in srgb, var(--glow-blue) 55%, transparent); animation: drift 26s ease-in-out infinite alternate; }
54
+ @keyframes drift { from { translate: 0 0; } to { translate: 4vw 3vh; } }
55
+ body:has(#view-games:not([hidden])) .aurora { opacity: .7; }
56
+
57
+ /* ---------- Left rail ---------- */
58
+ .rail {
59
+ position: fixed; inset: 0 auto 0 0; width: var(--rail-w); z-index: 30;
60
+ display: flex; flex-direction: column; align-items: center; padding: 10px 0 14px;
61
+ background: color-mix(in srgb, var(--panel) 92%, transparent); border-right: 1px solid var(--line);
70
62
  }
71
- .brand-text { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
72
- .brand-text b { background: linear-gradient(90deg, var(--accent), var(--accent-2)); -webkit-background-clip: text; background-clip: text; color: transparent; }
73
-
74
- .clock-island {
75
- display: flex; align-items: center; gap: 10px;
76
- padding: 8px 18px; border: 0; border-radius: 999px;
77
- background: var(--island); color: var(--island-text);
78
- box-shadow: var(--shadow), inset 0 0 0 1px rgba(255,255,255,.08);
79
- transition: transform .2s cubic-bezier(.3,1.6,.5,1), padding .2s;
63
+ .rail-logo { width: 38px; height: 38px; display: grid; place-items: center; margin-bottom: 14px; color: var(--text); border-bottom: 1px solid var(--line); padding-bottom: 12px; height: 50px; }
64
+ .rail-logo svg { width: 24px; height: 24px; fill: currentColor; }
65
+ .rail-group { display: flex; flex-direction: column; gap: 6px; }
66
+ .rail-group.bottom { margin-top: auto; }
67
+ .rail-btn {
68
+ width: 40px; height: 40px; display: grid; place-items: center; border: 0; border-radius: 8px;
69
+ background: transparent; color: var(--muted); transition: background .15s, color .15s;
80
70
  }
81
- .clock-island:hover { transform: scale(1.04); padding-inline: 22px; }
82
- .clock-island:active { transform: scale(.97); }
83
- .clock-dot { width: 8px; height: 8px; border-radius: 50%; background: #34d399; box-shadow: 0 0 10px #34d399; }
84
- .clock-time { font: 600 17px/1 ui-monospace, "SF Mono", Consolas, monospace; font-variant-numeric: tabular-nums; letter-spacing: .02em; }
85
- .clock-meta { font-size: 12px; opacity: .6; }
86
-
87
- .actions { display: flex; gap: 8px; justify-content: flex-end; }
88
- .icon-btn {
89
- display: inline-flex; align-items: center; gap: 6px;
90
- height: 38px; padding: 0 12px; border-radius: 12px;
91
- border: 1px solid var(--line); background: var(--bg-2);
92
- transition: background .15s, border-color .15s, transform .1s;
71
+ .rail-btn svg { width: 20px; height: 20px; fill: currentColor; }
72
+ .rail-btn:hover { color: var(--text); background: var(--soft); }
73
+ .rail-btn.active { background: var(--text); color: var(--bg); }
74
+ #panic-btn:hover { color: #fff; background: color-mix(in srgb, var(--danger) 70%, transparent); }
75
+
76
+ /* ---------- Clock (top-right) ---------- */
77
+ .clock {
78
+ position: fixed; top: 12px; right: 14px; z-index: 25;
79
+ padding: 7px 12px; border-radius: 6px; border: 1px solid var(--line); background: color-mix(in srgb, var(--panel) 85%, transparent);
80
+ font-weight: 600; font-size: 13px; font-variant-numeric: tabular-nums;
93
81
  }
94
- .icon-btn:hover { background: var(--card-hover); border-color: color-mix(in srgb, var(--accent) 50%, var(--line)); }
95
- .icon-btn:active { transform: translateY(1px); }
96
- .icon-btn .label { font-size: 13px; font-weight: 600; }
97
- .icon-btn.panic { border-color: color-mix(in srgb, var(--danger) 45%, var(--line)); }
98
- .icon-btn.panic:hover { background: color-mix(in srgb, var(--danger) 18%, var(--bg-2)); }
82
+ .clock small { margin-left: 5px; color: var(--muted); font-size: 11px; }
83
+
84
+ /* ---------- Layout ---------- */
85
+ .main { position: relative; z-index: 1; margin-left: var(--rail-w); min-height: 100vh; }
86
+ .view { padding: 0 clamp(16px, 3vw, 44px); }
99
87
 
100
88
  /* ---------- Home ---------- */
101
- main { flex: 1; width: 100%; max-width: 1400px; margin: 0 auto; padding: 24px clamp(16px, 3vw, 32px) 40px; }
102
- .hero { display: grid; gap: 14px; margin-bottom: 26px; }
103
- .search-wrap { position: relative; }
104
- .search-icon { position: absolute; left: 16px; top: 50%; width: 20px; height: 20px; transform: translateY(-50%); fill: var(--muted); }
105
- #search {
106
- width: 100%; height: 54px; padding: 0 52px 0 48px;
107
- border-radius: var(--radius); border: 1px solid var(--line);
108
- background: var(--bg-2); color: var(--text); font-size: 16px; outline: none;
109
- box-shadow: var(--shadow); transition: border-color .15s, box-shadow .15s;
89
+ .home { min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; padding-bottom: 12vh; }
90
+ .wordmark {
91
+ margin: 0 0 30px; font-size: clamp(64px, 11vw, 150px); font-weight: 800; letter-spacing: -.055em; line-height: .9;
92
+ background: linear-gradient(180deg, var(--text) 55%, color-mix(in srgb, var(--text) 70%, transparent));
93
+ -webkit-background-clip: text; background-clip: text; color: transparent;
94
+ }
95
+ .home-search {
96
+ position: relative; width: min(640px, 100%); height: 64px; display: flex; align-items: center; gap: 14px; padding: 0 22px;
97
+ background: color-mix(in srgb, var(--panel) 88%, transparent); border: 1px solid var(--line-2); border-radius: 4px;
98
+ box-shadow: 0 30px 60px -20px rgba(0,0,0,.8);
110
99
  }
111
- #search:focus { border-color: var(--accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 22%, transparent); }
112
- #search::-webkit-search-cancel-button { display: none; }
113
- .search-hint { position: absolute; right: 16px; top: 50%; transform: translateY(-50%); }
114
-
115
- .chips { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
116
- .chips::-webkit-scrollbar { display: none; }
117
- .chip {
118
- flex: none; padding: 6px 14px; border-radius: 999px;
119
- border: 1px solid var(--line); background: var(--bg-2); color: var(--muted);
120
- font-size: 13px; font-weight: 600;
100
+ .home-search svg { width: 20px; height: 20px; fill: var(--muted); flex: none; }
101
+ .home-search input { flex: 1; min-width: 0; border: 0; outline: 0; background: none; font-size: 17px; }
102
+ .home-search input::-webkit-search-cancel-button { display: none; }
103
+ .home-search:focus-within { border-color: color-mix(in srgb, var(--text) 40%, transparent); }
104
+ /* The light that sweeps along the bottom edge */
105
+ .sweep { position: absolute; left: 0; right: 0; bottom: -1px; height: 1px; overflow: hidden; }
106
+ .sweep::after {
107
+ content: ""; position: absolute; top: 0; width: 22%; height: 1px;
108
+ background: linear-gradient(90deg, transparent, var(--text), transparent);
109
+ animation: sweep 3.2s ease-in-out infinite;
121
110
  }
122
- .chip:hover { color: var(--text); }
123
- .chip[aria-selected="true"] { background: var(--accent); border-color: var(--accent); color: #fff; }
124
- .chip small { opacity: .7; font-weight: 500; margin-left: 4px; }
125
-
126
- .row { margin-bottom: 30px; }
127
- .row-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 12px; }
128
- .row-head h2 { font-size: 18px; margin: 0; }
129
- .count { color: var(--muted); font-size: 13px; }
130
- .text-btn { border: 0; background: none; color: var(--muted); font-size: 13px; font-weight: 600; padding: 4px 6px; border-radius: 8px; }
131
- .text-btn:hover { color: var(--text); background: var(--card-hover); }
132
-
133
- .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 14px; }
134
- .grid.recent { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
135
-
136
- .card {
137
- display: flex; flex-direction: column; text-align: left; padding: 0; overflow: hidden;
138
- border: 1px solid var(--line); border-radius: var(--radius); background: var(--card);
139
- transition: transform .15s, border-color .15s, box-shadow .15s;
140
- content-visibility: auto; contain-intrinsic-size: 200px;
111
+ @keyframes sweep { from { left: -22%; } to { left: 100%; } }
112
+ .home-sub { margin: 18px 0 0; color: var(--muted); font-size: 13px; }
113
+
114
+ /* ---------- Games page ---------- */
115
+ .games { padding-top: 26px; padding-bottom: 50px; }
116
+ .games-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; padding-right: 110px; }
117
+ .games-head h1 { margin: 0; font-size: 44px; font-weight: 800; letter-spacing: -.03em; }
118
+ .lede { margin: 4px 0 18px; color: var(--muted); }
119
+ .per-row { display: flex; align-items: center; gap: 2px; padding: 4px; border: 1px solid var(--line); border-radius: 4px; background: var(--panel); margin-top: 48px; }
120
+ .per-row span { color: var(--muted); font-size: 12px; padding: 0 10px; }
121
+ .per-row button { width: 32px; height: 28px; border: 0; border-radius: 3px; background: none; color: var(--muted); font-size: 13px; font-weight: 600; }
122
+ .per-row button:hover { color: var(--text); }
123
+ .per-row button.on { background: var(--text); color: var(--bg); }
124
+
125
+ .tabs { display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 4px; border: 1px solid var(--line); border-radius: 4px; background: var(--panel); margin-bottom: 16px; max-width: 100%; }
126
+ .tab { border: 0; border-radius: 3px; background: none; padding: 7px 14px; font-size: 13px; font-weight: 600; color: var(--muted); white-space: nowrap; }
127
+ .tab:hover { color: var(--text); }
128
+ .tab[aria-selected="true"] { background: var(--text); color: var(--bg); }
129
+ .tab small { opacity: .6; margin-left: 5px; font-weight: 500; }
130
+
131
+ .toolbar { display: flex; gap: 10px; align-items: center; margin-bottom: 26px; }
132
+ .search { flex: 1; display: flex; align-items: center; gap: 10px; height: 44px; padding: 0 14px; border: 1px solid var(--line-2); border-radius: 4px; background: color-mix(in srgb, var(--panel) 85%, transparent); }
133
+ .search:focus-within { border-color: color-mix(in srgb, var(--text) 40%, transparent); }
134
+ .search svg { width: 17px; height: 17px; fill: var(--muted); }
135
+ .search input { flex: 1; border: 0; outline: 0; background: none; }
136
+ .search input::-webkit-search-cancel-button { display: none; }
137
+ #sort { height: 44px; padding: 0 12px; border: 1px solid var(--line-2); border-radius: 4px; background: var(--panel); min-width: 150px; }
138
+ .count { color: var(--muted); font-size: 13px; white-space: nowrap; min-width: 76px; text-align: right; }
139
+
140
+ .block { margin-bottom: 30px; }
141
+ .block-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
142
+ .block-head h2 { margin: 0; font-size: 16px; font-weight: 700; }
143
+ .text-btn { border: 0; background: none; color: var(--muted); font-size: 13px; font-weight: 600; padding: 4px 8px; border-radius: 4px; }
144
+ .text-btn:hover { color: var(--text); background: var(--soft); }
145
+
146
+ /* ---------- Tiles ---------- */
147
+ .tile {
148
+ position: relative; display: block; padding: 0; border: 1px solid var(--line); border-radius: 6px; overflow: hidden;
149
+ background: var(--tile); text-align: left; aspect-ratio: 4 / 3; width: 100%;
150
+ transition: transform .2s ease, border-color .2s, box-shadow .2s;
141
151
  }
142
- .card:hover, .card:focus-visible {
143
- transform: translateY(-3px); outline: none;
144
- border-color: color-mix(in srgb, var(--accent) 60%, var(--line));
145
- box-shadow: 0 12px 28px color-mix(in srgb, var(--accent) 22%, transparent);
152
+ .tile:hover, .tile:focus-visible { transform: translateY(-3px); border-color: var(--line-2); box-shadow: 0 18px 40px -12px rgba(0,0,0,.8); outline: none; }
153
+ .tile:focus-visible { border-color: var(--text); }
154
+ .tile-art { position: absolute; inset: 0; display: grid; place-items: center; color: #fff; font-weight: 800; font-size: 34px; letter-spacing: -.02em; }
155
+ .tile-art img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .35s ease; }
156
+ .tile:hover .tile-art img { transform: scale(1.05); }
157
+ .tile::after { content: ""; position: absolute; inset: 45% 0 0; background: linear-gradient(180deg, transparent, rgba(0,0,0,.85)); pointer-events: none; }
158
+ .tile-label {
159
+ position: absolute; left: 12px; right: 12px; bottom: 10px; z-index: 1; color: #fff;
160
+ font-weight: 700; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 1px 6px rgba(0,0,0,.6);
146
161
  }
147
- .thumb {
148
- position: relative; aspect-ratio: 16 / 10; display: grid; place-items: center;
149
- color: #fff; font-weight: 800; font-size: 34px; letter-spacing: -.02em;
150
- text-shadow: 0 2px 12px rgba(0,0,0,.35); overflow: hidden;
162
+ .badge {
163
+ position: absolute; top: 10px; left: 10px; z-index: 1; padding: 3px 8px; border-radius: 3px;
164
+ background: rgba(0,0,0,.72); color: #fff; font-size: 12px; font-weight: 700;
151
165
  }
152
- .thumb::after {
153
- content: ""; position: absolute; inset: 0;
154
- background: radial-gradient(circle at 30% 20%, rgba(255,255,255,.28), transparent 55%);
166
+ .badge::before { content: "★ "; color: #facc15; }
167
+
168
+ .grid { display: grid; grid-template-columns: repeat(var(--per-row), minmax(0, 1fr)); gap: 14px; }
169
+ .recent-row { display: grid; grid-template-columns: repeat(var(--per-row), minmax(0, 1fr)); gap: 14px; }
170
+ .empty { text-align: center; color: var(--muted); padding: 50px 0; }
171
+
172
+ /* ---------- Popular games: smooth sideways loop ---------- */
173
+ .marquee {
174
+ overflow: hidden; margin: 0 calc(-1 * clamp(16px, 3vw, 44px)); padding: 6px 0 12px;
175
+ -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
176
+ mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
155
177
  }
156
- .thumb .emoji { position: absolute; right: 10px; bottom: 6px; font-size: 22px; opacity: .9; text-shadow: none; }
157
- .card .play { position: absolute; inset: 0; display: grid; place-items: center; background: rgba(0,0,0,.35); opacity: 0; transition: opacity .15s; z-index: 1; font-size: 30px; }
158
- .card:hover .play { opacity: 1; }
159
- .card-body { padding: 10px 12px 12px; display: grid; gap: 4px; }
160
- .card-name { font-weight: 650; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
161
- .card-meta { display: flex; justify-content: space-between; color: var(--muted); font-size: 12px; }
162
- .empty { text-align: center; color: var(--muted); padding: 40px 0; }
178
+ .marquee-track { display: flex; gap: 16px; width: max-content; will-change: transform; }
179
+ .marquee .tile { width: clamp(300px, 28vw, 440px); aspect-ratio: 16 / 9; flex: none; }
180
+ .marquee .tile-label { font-size: 17px; bottom: 14px; left: 16px; }
163
181
 
164
182
  /* ---------- Player ---------- */
165
- .player { position: fixed; inset: 0; z-index: 20; display: flex; flex-direction: column; background: var(--bg); }
166
- .player-bar { display: flex; align-items: center; gap: 12px; padding: 10px 16px; border-bottom: 1px solid var(--line); background: var(--bg-2); }
167
- .player-title { flex: 1; margin: 0; font-size: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
168
- .stage { position: relative; flex: 1; background: #000; }
183
+ .player { position: fixed; inset: 0; z-index: 40; display: flex; flex-direction: column; background: #000; }
184
+ .player-bar { display: flex; align-items: center; gap: 12px; padding: 8px 12px; background: #0a0a0c; border-bottom: 1px solid rgba(255,255,255,.08); color: #fff; }
185
+ .player-title { flex: 1; margin: 0; font-size: 15px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
186
+ .player-actions { display: flex; gap: 6px; }
187
+ .pill-btn { height: 32px; padding: 0 12px; border-radius: 4px; border: 1px solid rgba(255,255,255,.14); background: rgba(255,255,255,.06); color: #fff; font-size: 13px; font-weight: 600; }
188
+ .pill-btn:hover { background: rgba(255,255,255,.12); }
189
+ .pill-btn.danger:hover { background: var(--danger); border-color: var(--danger); }
190
+ .stage { position: relative; flex: 1; }
169
191
  #game-frame { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; background: #000; }
170
- .loader { position: absolute; inset: 0; display: grid; place-items: center; background: var(--bg); padding: 16px; }
171
- .loader-card { width: min(360px, 100%); text-align: center; }
172
- .loader-thumb { width: 120px; aspect-ratio: 16/10; margin: 0 auto 14px; border-radius: 14px; display: grid; place-items: center; color: #fff; font-weight: 800; font-size: 26px; box-shadow: var(--shadow); }
173
- .loader-name { font-weight: 700; font-size: 18px; margin: 0 0 14px; }
174
- .bar { height: 8px; border-radius: 999px; background: var(--line); overflow: hidden; }
175
- .bar-fill { height: 100%; width: 0; border-radius: inherit; background: linear-gradient(90deg, var(--accent), var(--accent-2)); transition: width .15s; }
176
- .loader-status { color: var(--muted); font-size: 13px; margin: 10px 0 4px; font-variant-numeric: tabular-nums; }
177
-
178
- /* ---------- Footer ---------- */
179
- .footer { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 16px clamp(16px, 3vw, 32px); color: var(--muted); font-size: 13px; border-top: 1px solid var(--line); }
192
+ .loader { position: absolute; inset: 0; display: grid; place-items: center; background: #000; color: #fff; padding: 16px; }
193
+ .loader-card { width: min(440px, 100%); text-align: center; }
194
+ .loader-art { width: 100%; aspect-ratio: 16/10; border-radius: 6px; margin-bottom: 18px; background: #111 center / cover no-repeat; border: 1px solid rgba(255,255,255,.1); display: grid; place-items: center; font-size: 42px; font-weight: 800; }
195
+ .loader-name { font-weight: 800; font-size: 22px; letter-spacing: -.02em; margin: 0 0 4px; }
196
+ .loader-desc { color: rgba(255,255,255,.55); font-size: 13px; margin: 0 0 18px; }
197
+ .bar { height: 2px; background: rgba(255,255,255,.12); overflow: hidden; }
198
+ .bar-fill { height: 100%; width: 0; background: #fff; transition: width .15s; }
199
+ .loader-status { color: rgba(255,255,255,.55); font-size: 12px; margin: 10px 0 8px; font-variant-numeric: tabular-nums; }
200
+
201
+ /* ---------- Corner ---------- */
202
+ .corner-links { position: fixed; right: 14px; bottom: 12px; z-index: 5; display: flex; gap: 8px; }
203
+ .corner-links > span { padding: 6px 10px; border: 1px solid var(--line); border-radius: 4px; background: color-mix(in srgb, var(--panel) 85%, transparent); font-size: 12px; color: var(--muted); }
180
204
  body.playing { overflow: hidden; }
205
+ body:has(#view-games:not([hidden])) .corner-links { display: none; }
181
206
 
182
- /* ---------- Small screens ---------- */
183
- @media (max-width: 760px) {
184
- .topbar { grid-template-columns: 1fr auto; }
185
- .clock-island { grid-column: 1 / -1; grid-row: 2; justify-self: center; }
186
- .icon-btn .label { display: none; }
187
- .brand-text { font-size: 14px; }
188
- .grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; }
189
- .search-hint { display: none; }
207
+ /* ---------- Responsive ---------- */
208
+ @media (max-width: 1100px) { .grid, .recent-row { grid-template-columns: repeat(min(var(--per-row), 4), minmax(0, 1fr)); } }
209
+ @media (max-width: 720px) {
210
+ :root { --rail-w: 0px; }
211
+ .rail { inset: auto 0 0 0; width: auto; height: 56px; flex-direction: row; justify-content: space-around; padding: 0 8px; border-right: 0; border-top: 1px solid var(--line); }
212
+ .rail-logo { display: none; }
213
+ .rail-group, .rail-group.bottom { flex-direction: row; margin: 0; }
214
+ .main { padding-bottom: 70px; }
215
+ .games-head { flex-direction: column; padding-right: 0; }
216
+ .per-row { display: none; }
217
+ .grid, .recent-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
218
+ .toolbar { flex-wrap: wrap; }
219
+ #sort { min-width: 0; flex: 1; }
220
+ .marquee .tile { width: 260px; }
221
+ .corner-links { display: none; }
222
+ .clock { top: 8px; right: 8px; }
190
223
  }
224
+ @media (prefers-reduced-motion: reduce) { .aurora span, .sweep::after { animation: none; } }