PageSourceSearch

https://memorin.app/lab/skins/

html memorin.app collected 2026-10-02 01:14:11 UTC 84,212 bytes, 1,343 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3<head>
4<meta charset="utf-8">
5<title>Free CS2 Demo Viewer in 3D — Then Play the Moment | Memorin</title>
6<meta name="viewport" content="width=device-width, initial-scale=1">
7<meta name="description" content="Free CS2 demo viewer: watch any Counter-Strike 2 match in full 3D in your browser, then take over the moment and play it. No download, no account to try.">
8<meta name="robots" content="index, follow">
9<link rel="canonical" href="https://memorin.app/">
10
11<meta property="og:type" content="website">
12<meta property="og:site_name" content="Memorin">
13<meta property="og:title" content="CS2 Demo Viewer in 3D — Then Play the Moment">
14<meta property="og:description" content="Watch any CS2 match in full 3D in your browser, then take over the situation and play it differently. No download, no account to try.">
15<meta property="og:url" content="https://memorin.app/">
16<meta property="og:image" content="https://memorin.app/assets/og-preview.png">
17
18<meta name="twitter:card" content="summary_large_image">
19<meta name="twitter:title" content="CS2 Demo Viewer in 3D — Then Play the Moment">
20<meta name="twitter:description" content="Watch any CS2 match in full 3D in your browser, then take over the situation and play it differently. No download, no account to try.">
21<meta name="twitter:image" content="https://memorin.app/assets/og-preview.png">
22
23<script nonce="t92TkfDfjA/i25i0rq4miQ==" type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://memorin.app/#organization","name":"Memorin","url":"https://memorin.app/","sameAs":["https://x.com/memorinapp","https://www.youtube.com/@memorinapp","https://alternativeto.net/software/memorin/","https://www.producthunt.com/products/memorin-free-cs2-demo-viewer"],"logo":{"@type":"ImageObject","@id":"https://memorin.app/#logo","url":"https://memorin.app/assets/brand/logo-512.png","width":512,"height":512}},{"@type":"WebSite","@id":"https://memorin.app/#website","url":"https://memorin.app/","name":"Memorin","description":"Watch Counter-Strike 2 matches in full 3D in the browser, then take over the moment and play it yourself.","publisher":{"@id":"https://memorin.app/#organization"}},{"@type":"WebApplication","@id":"https://memorin.app/#application","name":"Memorin","alternateName":["Memorin CS2 Demo Viewer","Memorin Replay Moments"],"url":"https://memorin.app/","description":"Watch Counter-Strike 2 demos as full 3D browser replays, then take control of any situation and replay it differently. Includes browser Deathmatch, a first-person skin viewer and utility practice.","applicationCategory":"GameApplication","applicationSubCategory":"Replay, practice and match review","operatingSystem":"Any","browserRequirements":"Requires JavaScript and WebGL","featureList":["Full 3D CS2 demo viewer","Playable Replay Moments","Utility and grenade practice","Browser Deathmatch","First-person skin viewer","Match and utility analysis"],"offers":[{"@type":"Offer","name":"Memorin Free","price":"0","priceCurrency":"EUR","description":"Play the daily moment with no account. A signed-in free account watches demos, reviews matches, and adds one demo a day — uploaded or imported. Free demos are kept on the server for 48 hours and saved on the device by the browser."},{"@type":"Offer","name":"Memorin PRO","availability":"https://schema.org/InStock","description":"The full Rematch report on every match, every moment from your own matches, creating and sharing your own moments, unlimited practice, unlimited demos with 30-day storage, and the advanced demo controls."}],"publisher":{"@id":"https://memorin.app/#organization"},"isPartOf":{"@id":"https://memorin.app/#website"}}]}</script>
vendor: 1 bytes, line 23
23
24<script nonce="t92TkfDfjA/i25i0rq4miQ==" type="application/ld+json">{"@context":"https://schema.org","@type":"FAQPage","@id":"https://memorin.app/#faq","mainEntity":[{"@type":"Question","name":"Can I watch CS2 demos in the browser?","acceptedAnswer":{"@type":"Answer","text":"Yes. Upload a Counter-Strike 2 .dem file to Memorin and it becomes a full 3D browser replay with real map geometry, player movement, utility, HUD, POV, follow and free-camera controls."}},{"@type":"Question","name":"What is a Replay Moment?","acceptedAnswer":{"@type":"Answer","text":"A Replay Moment is a real situation from a real match that you can play yourself. Memorin rebuilds the positions, utility, health and clock, then hands you control so you can try a different decision."}},{"@type":"Question","name":"Is Memorin free?","acceptedAnswer":{"@type":"Answer","text":"Playing the daily moment needs no account at all. A free signed-in account watches demos, uses match review, and adds one demo a day — uploaded or imported, either counts. Free demos are kept on the server for 48 hours, and your browser saves its own copy so the match stays watchable after that. PRO adds the full Rematch report on every match, every moment from your own matches, creating and sharing your own moments, unlimited practice, unlimited demos with 30-day storage, and the advanced demo controls."}},{"@type":"Question","name":"Are uploaded CS2 demos private?","acceptedA
24nswer":{"@type":"Answer","text":"Private demos and parsed replay data are available only to the account that uploaded them. Memorin retains private demos and derived caches for 30 days on PRO and 48 hours on the free tier, and account controls let users delete individual demos or their account."}},{"@type":"Question","name":"Is Memorin affiliated with Valve?","acceptedAnswer":{"@type":"Answer","text":"No. Memorin is not affiliated with or endorsed by Valve. Counter-Strike 2 is a trademark of Valve Corporation."}}]}</script>
24
25
26<link rel="icon" type="image/png" sizes="16x16" href="/assets/brand/favicon-fill-16.png">
27<link rel="icon" type="image/png" sizes="32x32" href="/assets/brand/favicon-fill-32.png">
28<link rel="icon" type="image/png" sizes="48x48" href="/assets/brand/favicon-fill-48.png">
29<link rel="apple-touch-icon" sizes="180x180" href="/assets/brand/apple-touch-icon.png">
30<link rel="manifest" href="/assets/brand/manifest.json">
31<link rel="preload" as="font" type="font/woff2" crossorigin href="/fonts/saira-condensed-700-latin.4773efcf.woff2">
32<link rel="preload" as="font" type="font/woff2" crossorigin href="/fonts/saira-latin.d00e2191.woff2">
33<link rel="stylesheet" href="/css/style.min.css?v=d7dd315bd8">
34<link rel="stylesheet" href="/css/cs2hud/fonts.css?v=2e8c66b689" data-cs2hud="fonts">
35<link rel="stylesheet" href="/css/cs2hud/vars.css?v=2e8c66b689" data-cs2hud="vars">
36<link rel="stylesheet" href="/css/cs2hud/shared.css?v=2e8c66b689" data-cs2hud="shared">
37<link rel="stylesheet" href="/css/cs2hud/frame.css?v=2e8c66b689" data-cs2hud="frame">
38<link rel="stylesheet" href="/css/cs2hud/hud.css?v=2e8c66b689" data-cs2hud="hud">
39<link rel="stylesheet" href="/css/cs2hud/hudteamcounter.css?v=2e8c66b689" data-cs2hud="hudteamcounter">
40<link rel="stylesheet" href="/css/cs2hud/hudalerts.css?v=2e8c66b689" data-cs2hud="hudalerts">
41<link rel="stylesheet" href="/css/cs2hud/buymenu.css?v=2e8c66b689" data-cs2hud="buymenu">
42<script nonce="t92TkfDfjA/i25i0rq4miQ==" type="importmap">
43{
44  "imports": {
45    "three": "/vendor/three/build/three.module.js",
46    "three/addons/": "/vendor/three/examples/jsm/",
47    "three-mesh-bvh": "/vendor/three-mesh-bvh/build/index.module.js"
48  }
49}
50</script>
50
51<link rel="preconnect" href="https://assets.memorin.app" crossorigin><link rel="dns-prefetch" href="https://assets.memorin.app">
51<script nonce="t92TkfDfjA/i25i0rq4miQ==">window.__ASSET_BASE__="https://assets.memorin.app";window.__ASSET_REVISION__="202637af";window.__JS_CHUNK_V__="5028812bb7";window.__CLIENT_BUILD__="bc22b8b0df27"</script>
51</head>
52<body>
53
54<nav id="viewer-rail" class="hidden" aria-label="Viewer">
55  
56  <button class="vr-btn vr-back" type="button" data-proxy="btn-main" title="Back — leave this demo or moment and return where you came from">
57    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M19 12H5"/><path d="m11 6-6 6 6 6"/></svg>
58    <span>Back</span>
59  </button>
60  <span class="vr-div" aria-hidden="true"></span>
61  
62  <button class="vr-btn vr-moment" type="button" data-proxy="death-hint" data-key="H" title="Reveal what killed you — marks the attempt and caps the grade (H)">
63    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M12 3a6 6 0 0 0-3.5 10.9V17h7v-3.1A6 6 0 0 0 12 3Z"/><path d="M10 20h4"/></svg>
64    <span>Hint</span>
65  </button>
66  <button class="vr-btn vr-moment" type="button" data-proxy="intervention-retry" data-key="R" title="Replay this moment from the start (R)">
67    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M20 12a8 8 0 1 1-2.5-5.8"/><path d="M20 4v4h-4"/></svg>
68    <span>Replay</span>
69  </button>
70  <button class="vr-btn vr-moment" type="button" data-proxy="death-share" title="Share this moment">
71    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><circle cx="18" cy="5" r="2.6"/><circle cx="6" cy="12" r="2.6"/><circle cx="18" cy="19" r="2.6"/><path d="m8.4 10.8 7.2-4.2M8.4 13.2l7.2 4.2"/></svg>
72    <span>Share</span>
73  </button>
74  <button class="vr-btn vr-moment" type="button" data-proxy="intervention-next" data-key="N" title="Next moment (N)">
75    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="m7 5 9 7-9 7z"/><path d="M18 5v14"/></svg>
76    <span>Next</span>
77  </button>
78  <span class="vr-div vr-moment" aria-hidden="true"></span>
79  <button class="vr-btn vr-watch" type="button" data-proxy="btn-review" data-key="R" title="Match review (R)">
80    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M4 5h16v14H4z"/><path d="M4 9h16M9 9v10"/></svg>
81    <span>Review</span>
82  </button>
83  
84  <button class="vr-btn vr-watch" type="button" data-proxy="btn-scoreboard" data-key="TAB" title="Scoreboard (TAB)">
85    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M4 6h16M4 12h16M4 18h16"/></svg>
86    <span>Scores</span>
87  </button>
88  <button class="vr-btn vr-watch" type="button" data-proxy="btn-tacmap" data-key="T" title="Tactical map (T)">
89    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M4 6.5 9.5 4l5 2.5L20 4v13.5L14.5 20l-5-2.5L4 20zM9.5 4v13.5M14.5 6.5V20"/></svg>
90    <span>Map</span>
91  </button>
92  
93  <button class="vr-btn vr-watch" type="button" data-proxy="btn-pov" data-key="V" title="What he could see — look through this player's eyes (V)">
94    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M3 12h4l2-4 3 8 2.5-5 1.5 3h5"/><circle cx="12" cy="12" r="9"/></svg>
95    <span>His view</span>
96  </button>
97  <button class="vr-btn vr-watch" type="button" data-proxy="btn-xray-toggle" data-key="X" title="Players through walls (X)">
98    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><circle cx="12" cy="12" r="3"/><path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6-10-6-10-6Z"/></svg>
99    <span>X-ray</span>
100  </button>
101  <button class="vr-btn vr-watch" type="button" data-proxy="btn-walk" data-key="B" title="Walk the map (B)">
102    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><circle cx="13" cy="4" r="2"/><path d="m9 21 3-6 3 3v4M9 12l3-3 4 2"/></svg>
103    <span>Walk</span>
104  </button>
105  <button class="vr-btn vr-watch" type="button" data-proxy="btn-freecam" data-key="C" title="Freecam from the current view (C)">
106    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="m4 12 5-5 5 5-5 5zM14 7l3-3 3 3-3 3zM14 17l3-3 3 3-3 3z"/><path d="m12 12 3-3M12 12l3 3"/></svg>
107    <span>Freecam</span>
108  </button>
109  <button class="vr-btn vr-watch" type="button" data-proxy="btn-create-replay" title="Create a replay moment">
110    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M5 6h14v12H5zM9 3v6M15 3v6M9 15h6"/></svg>
111    <span>Moment</span>
112  </button>
113  
114  <button class="vr-btn vr-soon vr-watch" type="button" disabled title="Ask the match — coming soon" aria-disabled="true">
115    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M12 3l1.8 4.8L18.5 9.5l-4.7 1.7L12 16l-1.8-4.8L5.5 9.5l4.7-1.7Z"/><path d="M18.5 15.5l.9 2.1 2.1.9-2.1.9-.9 2.1-.9-2.1-2.1-.9 2.1-.9Z"/></svg>
116    <span>AI</span>
117  </button>
118  <span class="vr-div" aria-hidden="true"></span>
119  
120  <button class="vr-btn" type="button" data-proxy="btn-input-overlay" data-key="K" title="Keys and mouse (K)">
121    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><rect x="2" y="7" width="14" height="10" rx="2"/><rect x="18" y="6" width="4" height="7" rx="2"/></svg>
122    <span>
122Inputs</span>
123  </button>
124  <button class="vr-btn" type="button" data-proxy="btn-spray-review" data-key="I" title="Spray review (I)">
125    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" aria-hidden="true"><path d="M6 20h0M9 15h0M13 11h0M18 8h0"/><circle cx="18" cy="8" r="4" stroke-width="1.4"/></svg>
126    <span>Spray</span>
127  </button>
128  <button class="vr-btn" type="button" data-proxy="btn-nade-trails" data-key="N" title="Team-coloured grenade trails (N)">
129    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M3 20c6-2 9-6 11-11" stroke-dasharray="3 3"/><circle cx="17" cy="6" r="2.5"/></svg>
130    <span>Trails</span>
131  </button>
132  <button class="vr-btn vr-watch" type="button" data-proxy="btn-geo-toggle" data-key="U" title="3D map geometry (U)">
133    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="m12 3 8 4.5v9L12 21l-8-4.5v-9Z"/><path d="M12 12v9M12 12 4 7.5M12 12l8-4.5"/></svg>
134    <span>Geometry</span>
135  </button>
136  
137  <button class="vr-btn" type="button" data-proxy="btn-map-toggle" data-key="M" title="Overhead radar (M)">
138    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="4"/><path d="M12 3v3M12 18v3M3 12h3M18 12h3"/></svg>
139    <span>Radar</span>
140  </button>
141  
142  <button class="vr-btn" type="button" data-proxy="btn-fps-mode" title="FPS mode — drop the sky and distant scenery, render smoke at half resolution. Trades looks for frames.">
143    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M13 2 4 14h6l-1 8 9-12h-6z"/></svg>
144    <span>FPS</span>
145  </button>
146  <button class="vr-btn" type="button" data-proxy="btn-hud-toggle" data-key="H" title="Hide every HUD overlay (H)">
147    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6-10-6-10-6Z"/><path d="m3 3 18 18"/></svg>
148    <span>HUD</span>
149  </button>
150  <button class="vr-btn vr-watch" type="button" data-proxy="btn-skip-freeze" data-key="Z" title="Skip the current freeze time (Z)">
151    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M5 5v14l8-7zM15 5v14M19 5v14"/></svg>
152    <span>Skip freeze</span>
153  </button>
154  <span class="vr-div" aria-hidden="true"></span>
155  <button class="vr-btn" type="button" data-proxy="btn-screenshot" title="Save a HUD-free screenshot">
156    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M4 8h4l1.5-2h5L16 8h4v11H4z"/><circle cx="12" cy="13" r="3.2"/></svg>
157    <span>Shot</span>
158  </button>
159  <button class="vr-btn vr-watch" type="button" data-proxy="btn-share" title="Copy link to this view">
160    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><circle cx="18" cy="5" r="2.6"/><circle cx="6" cy="12" r="2.6"/><circle cx="18" cy="19" r="2.6"/><path d="m8.4 10.8 7.2-4.2M8.4 13.2l7.2 4.2"/></svg>
161    <span>Share</span>
162  </button>
163  <button id="vr-immersive" class="vr-btn" type="button" aria-pressed="false" title="Hide the rail and dock — the render fills the window">
164    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M4 9V4h5M20 9V4h-5M4 15v5h5M20 15v5h-5"/></svg>
165    <span>Immersive</span>
166  </button>
167</nav>
168<div id="viewer-tools" class="hidden" aria-label="Viewer tools">
169  <button id="btn-settings" type="button" title="Viewer tools" aria-label="Viewer tools" aria-haspopup="true" aria-expanded="false" aria-controls="settings-menu">
170    <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 8.5a3.5 3.5 0 1 0 0 7 3.5 3.5 0 0 0 0-7zM19 13.5v-3l-2.1-.6-.5-1.2 1.1-1.9-2.2-2.2-1.9 1.1-1.2-.5L11.5 3h-3l-.6 2.1-1.2.5-1.9-1.1-2.2 2.2 1.1 1.9-.5 1.2L1 10.5v3l2.1.6.5 1.2-1.1 1.9 2.2 2.2 1.9-1.1 1.2.5.6 2.1h3l.6-2.1 1.2-.5 1.9 1.1 2.2-2.2-1.1-1.9.5-1.2z"/></svg>
171  </button>
172  
173  <div id="settings-menu" class="hidden" role="menu" aria-label="Tools">
174    <div class="settings-head"><span>More</span><small>Settings and session</small></div>
175    <button id="btn-fps-mode" role="switch" aria-pressed="false" title="Drop the sky and outside scener
175y and render smoke at half resolution — trades looks for frames"><span>FPS mode</span><i class="fps-state">Off</i></button>
176    <button id="btn-nade-trails" role="switch" aria-pressed="false" title="Team-colored grenade trails"><span>Nade trails</span><kbd>N</kbd><i class="switch-state">Off</i></button>
177    <button id="btn-input-overlay" role="switch" aria-pressed="false"><span>Input overlay</span><kbd>K</kbd><i class="switch-state">Off</i></button>
178    <button id="btn-xray-toggle" role="switch" aria-pressed="false" title="Players through walls"><span>X-ray</span><kbd>X</kbd><i class="switch-state">Off</i></button>
179    <button id="btn-spray-review" role="switch" aria-pressed="false" title="The followed player's whole burst, in fire order"><span>Spray review</span><kbd>I</kbd><i class="switch-state">Off</i></button>
180    <button id="btn-map-toggle" role="switch" aria-pressed="true" title="Overhead radar"><span>Map radar</span><kbd>M</kbd><i class="switch-state">On</i></button>
181    <button id="btn-geo-toggle" role="switch" aria-pressed="true" title="3D map geometry"><span>Map geometry</span><kbd>U</kbd><i class="switch-state">On</i></button>
182    <button id="btn-hud-toggle" role="switch" aria-pressed="false" title="Hide HUD overlays"><span>Hide HUD</span><kbd>H</kbd><i class="switch-state">Off</i></button>
183    
184    <div class="settings-rule"></div>
185    <button id="btn-pov" role="switch" aria-pressed="false" title="Look through this player's eyes — and back out again"><span>What he could see</span><kbd>V</kbd><i class="switch-state">Off</i></button>
186    <button id="btn-walk" role="menuitem" title="Walk the map as a CS player (B) · WASD move, Space jump, Ctrl crouch, Esc exit"><span>Walk the map</span><kbd>B</kbd></button>
187    <button id="btn-freecam" role="menuitem" title="Freecam from the current view (C) · WASD move, Space/Control up/down"><span>Freecam</span><kbd>C</kbd></button>
188    <button id="btn-skip-freeze" role="menuitem" title="Skip the current freeze time (Z)"><span>Skip freeze time</span><kbd>Z</kbd></button>
189    <button id="btn-review" role="menuitem" title="Open match review (R)"><span data-i18n="review">Match review</span><kbd>R</kbd></button>
190    <button id="btn-create-replay" role="menuitem" title="Create a replay moment from this demo"><span>Create replay moment</span><i>PRO</i></button>
191    <button id="btn-tacmap" role="menuitem" title="The whole round from above"><span>Tactical map</span><kbd>T</kbd></button>
192    <button id="btn-scoreboard" role="menuitem" title="Toggle scoreboard"><span data-i18n="scoreboard">Scoreboard</span><kbd>TAB</kbd></button>
193    <button id="btn-screenshot" role="menuitem" title="Save a HUD-free screenshot"><span data-i18n="camera">Save screenshot</span></button>
194    <button id="btn-share" role="menuitem" title="Copy link to this view"><span data-i18n="share">Copy replay link</span></button>
195    <button id="btn-fullscreen" role="menuitem" title="Toggle fullscreen"><span>Fullscreen</span><kbd>F11</kbd></button>
196    <div class="settings-rule"></div>
197    <button id="btn-demos" role="menuitem" title="Open demos and upload"><span data-i18n="demos">Demos &amp; upload</span></button>
198    <button id="btn-main" role="menuitem" title="Unload the current demo and return to the homepage"><span>Back to main</span></button>
199  </div>
200</div>
201<button id="immersive-exit" type="button">Exit immersive</button>
202
203<div id="stage">
204<canvas id="gl"></canvas>
205
206<div id="skin-viewer-hud" class="skin-viewer-hud hidden" aria-live="polite">
207  <div class="skin-viewer-copy">
208    <span>Current CS2 finish · drag to orbit · wheel to zoom</span>
209    <strong id="skin-viewer-name">Skin viewer</strong>
210  </div>
211  <label for="skin-viewer-map"><span>CS2 lighting</span><select id="skin-viewer-map"></select></label>
212  <button id="skin-viewer-walk" type="button">Walk this map</button>
213  <button id="skin-viewer-close" type="button">Back to skins</button>
214</div>
215
216<section id="multi-pov-overlay" class="hidden" aria-label="Multiple POVs grid"></section>
217<div id="multi-pov-tools" class="hidden" aria-label="POV feed visibility">
218  <span id="mpt-count" aria-hidden="true">10/10</span>
219  <button id="mpt-all" type="button" role="switch" aria-pressed="true" title="Show every player's feed">All</button>
220  <button id="mpt-ct" type="button" role="switch" aria-pressed="false" title="Show only the CT side — five feeds">CT</button>
221  <button id="mpt-t" type="button" role="switch" aria-pressed="false" title="Show only the T side — five feeds">T</button>
222  <span id="mpt-restore" hidden aria-label="Hidden feeds — select to restore"></span>
223</div>
224
225<div id="topbar" class="hidden">
226  <div class="score ct"><span id="ct-name">CT</span><span id="ct-score">0</span></div>
227  <div id="clock">
228    <div id="round-label">ROUND 1</div>
229    <div id="round-timer">1:55</div>
230    <div id="objective-status"></div>
231  </div>
232  <div class="score t"><span id="t-score">0</span><span id="t-name">T</span></div>
233</div>
234<div id="capability-warning" class="hidden" role="status"></div>
235
236<div id="killfeed"></div>
237
238<div id="panel-ct" class="team-panel left"></div>
239<div id="panel-t" class="team-panel right"></div>
240
241<div id="voice-list" class="hidden" aria-live="off"></div>
242
243<canvas id="minimap" width="288" height="288" class="hidden"></canvas>
244<button id="radar-layer" class="hidden" type="button" title="Radar floor: automatic">AUTO</button>
245
246<div id="controls" class="hidden" aria-label="Replay controls">
247  
248  <div id="round-strip" class="hidden" aria-label="Rounds">
249    <button id="round-prev" class="round-page" type="button" aria-label="Earlier rounds">
250      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="m14 6-6 6 6 6"/></svg>
251    </button>
252    <button id="round-all" class="round-chip round-chip--all" type="button" aria-pressed="true">All</button>
253    <div id="round-track" role="tablist" aria-label="Jump to round"></div>
254    <button id="round-next" class="round-page" type="button" aria-label="Later rounds">
255      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="m10 6 6 6-6 6"/></svg>
256    </button>
257  </div>
258
259  <div id="buffer-chip" class="hidden"></div>
260  <div class="timeline-row">
261    <span class="timeline-kicker">Replay</span>
262    <div id="timeline" role="slider" tabindex="0" aria-label="Replay timeline" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
263    <div id="timeline-fill"></div>
264    <div id="timeline-markers"></div>
265    <div id="replay-range" class="hidden" aria-label="Replay moment selection">
266      <div class="replay-range-window" aria-hidden="true"></div>
267      <button id="replay-range-start" class="replay-range-handle start" type="button" aria-label="Drag replay start"><span id="replay-range-start-label">0:00</span></button>
268      <button id="replay-range-end" class="replay-range-handle end" type="button" aria-label="Drag replay end"><span id="replay-range-end-label">0:00</span></button>
269    </div>
270    </div>
271    <span id="time-label">0:00 / 0:00</span>
272  </div>
273
274  
275  <section id="replay-builder" class="hidden" aria-label="Create replay moment">
276    <div class="replay-builder-intro">
277      <span>Create replay moment</span>
278      <strong>Clip the yellow range</strong>
279      <small>Drag either timeline edge · 1–45 seconds</small>
280    </div>
281    <div class="replay-builder-fields">
282      <label><span>Player</span><select id="replay-builder-player"></select></label>
283      <label class="replay-builder-title"><span>Title <small>optional</small></span><input id="replay-builder-title" maxlength="80" placeholder="My connector retake"></label>
284    </div>
285    <input id="replay-builder-start" type="hidden">
286    <input id="replay-builder-end" type="hidden">
287    <div class="replay-builder-result">
288      <span id="replay-builder-duration">Selected clip</span>
289      <small id="replay-builder-status" role="status">Only recorded events are used.</small>
290    </div>
291    <div class="replay-builder-actions">
292      <button id="replay-builder-preview" type="button">Preview selection</button>
293      <button id="replay-builder-save" type="button">Analyze &amp; save</button>
294      <button id="replay-builder-open" class="hidden" type="button">Open My Moments</button>
295    </div>
296    <button id="replay-builder-close" type="button" aria-label="Close replay creator">×</button>
297  </section>
298
299  <div id="controls-row">
300    <div class="control-cluster transport-cluster" aria-label="Transport">
301      <button id="btn-prev" class="icon-btn" title="Previous round (Shift+Left)" aria-label="Previous round">
302        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 5v14M18 6l-9 6 9 6z"/></svg>
303      </button>
304      <button id="btn-rewind" class="icon-btn rewind-btn" title="Rewind 10 seconds (J)" aria-label="Rewind 10 seconds">
305        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 8V3m0 5h5M5.6 7A8 8 0 1 1 4 14"/></svg><b>10</b>
306      </button>
307      <button id="btn-step-back" class="icon-btn subtle-control" title="Previous snapshot (,)" aria-label="Previous snapshot">
308        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M8 5v14M18 6l-8 6 8 6z"/></svg>
309      </button>
310      <button id="btn-play" class="play-btn" title="Play (Space)" aria-label="Play" aria-pressed="false">
311        <svg class="play-glyph" viewBox="0 0 24 24" aria-hidden="true"><path d="m9 6 9 6-9 6z"/></svg>
312        <svg class="pause-glyph" viewBox="0 0 24 24" aria-hidden="true"><path d="M8 6h3v12H8zM14 6h3v12h-3z"/></svg>
313      </button>
314      <button id="btn-step-forward" class="icon-btn subtle-control" title="Next snapshot (.)" aria-label="Next snapshot">
315        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M16 5v14M6 6l8 6-8 6z"/></svg>
316      </button>
317      <button id="btn-next" class="icon-btn" title="Next round (Shift+Right)" aria-label="Next round">
318        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M18 5v14M6 6l9 6-9 6z"/></svg>
319      </button>
320    </div>
321
322    <div class="controls-side controls-side--left">
323    <div class="control-cluster event-cluster" aria-label="Events">
324      <button id="btn-prev-event" class="text-control" title="Previous event (Q) · previous death (Shift+Q)">
325        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="m14 7-5 5 5 5M19 5l-3 3M19 19l-3-3"/></svg><span>Event</span>
326      </button>
327      <button id="btn-next-event" class="text-control" title="Next event (E) · next death (Shift+E)">
328        <span>Event</span><svg viewBox="0 0 24 24" aria-hidden="true"><path d="m10 7 5 5-5 5M5 5l3 3M5 19l3-3"/></svg>
329      </button>
330    </div>
331    <div class="playback-selects">
332      <label class="control-field compact-field"><span>Speed</span><select id="speed" aria-label="Playback speed">
333        <option value="0.25">0.25×</option>
334        <option value="0.5">0.5×</option>
335        <option value="1" selected>1×</option>
336        <option value="2">2×</option>
337        <option value="4">4×</option>
338        <option value="8">8×</option>
339      </select></label>
340      <label class="control-field camera-field"><span>View</span><select id="cam-mode" aria-label="Camera view">
341        <option value="free">Free camera</option>
342        <option value="follow">Follow player</option>
343        <option value="pov">Player POV</option>
344        <option value="top">Top-down</option>
345        <option value="multi">Multiple POVs</option>
346        <option value="director" hidden>Broadcast camera</option>
347      </select></label>
348      <span id="follow-label" aria-live="polite"></span>
349    </div>
350    </div>
351
352    <div class="controls-side controls-side--right">
353
354    <div class="control-cluster utility-cluster">
355      <label class="volume-control" title="Volume">
356        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 10v4h4l5 4V6l-5 4zM17 9a4 4 0 0 1 0 6M19 6a8 8 0 0 1 0 12"/></svg>
357        <span class="sr-only">Volume</span><input type="range" id="volume" min="0" max="1" step="0.05" value="0.5">
358      </label>
359      <label class="control-field seek-field"><span>Seek</span><select id="seek-interval" title="How far the seek shortcuts jump" aria-label="Seek shortcut interval">
360        <option value="1">1 sec</option>
361        <option value="5" selected>5 sec</option>
362        <option value="10">10 sec</option>
363        <option value="30">30 sec</option>
364      </select></label>
365      <label class="auto-freeze-control" title="Automatically jump to the end of freeze time when playback enters a round">
366        <input id="auto-skip-freeze" type="checkbox">
367        <span>Skip freeze</span><kbd>Z</kbd>
368      </label>
369    </div>
370
371    <button id="btn-create-replay-dock" class="create-replay-control" type="button" title="Create a replay moment from this demo">
372      <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 6h14v12H5zM9 3v6M15 3v6M9 15h6"/></svg>
373      <span>Create moment</span><i>PRO</i>
374    </button>
375
376    <div class="session-controls">
377      <span id="map-label"></span>
378      <select id="demo-select" aria-label="Current demo"></select>
379      <button id="btn-upload" class="upload-control" title="Upload a .dem file" data-i18n="upload">Upload</button>
380    </div>
381    </div>
382    <input type="file" id="file-input" accept=".dem,.gz,.zst,.bz2" style="display:none">
383  </div>
384</div>
385
386<section id="comms-panel" class="hidden" aria-label="Demo communications">
387  <div id="comms-controls">
388    <button id="toggle-chat" type="button" aria-pressed="false" data-i18n="chatOff">Chat off</button>
389    <button id="toggle-radio" type="button" aria-pressed="false" data-i18n="radioOff">Radio off</button>
390    
391
392  </div>
393  <div id="comms-feed" aria-live="polite"></div>
394</section>
395
396<section id="scoreboard" class="hidden" aria-label="Scoreboard">
397  <div id="scoreboard-content"></div>
398</section>
399
400<section id="tacmap" class="hidden" aria-label="Tactical map">
401  <div id="tacmap-box">
402    <canvas id="tacmap-canvas"></canvas>
403    <div id="tacmap-foot">
404      <span class="tm-keys"><span class="tm-keys-close"><b>SHIFT</b> Close <i>·</i> </span><b>SPACE</b> Clear drawing <i>·</i> <span class="tm-keys-2d"><b>SHIFT+SPACE</b> Play/pause <i>·</i> </span><b>CLICK</b> <span class="tm-keys-3d">Player POV</span><span class="tm-keys-2d">Select player</span></span>
405      <button id="tacmap-layer" class="hidden" type="button">AUTO</button>
406    </div>
407  </div>
408</section>
409
410<div id="flash-overlay"></div>
411<div id="damage-overlay"></div>
412<div id="win-banner" class="hidden"></div>
413<div id="scope-overlay" class="hidden"><div class="lens-blur"></div><div class="ring"></div><div class="hline"></div><div class="vline"></div></div>
414<div id="crosshair" class="hidden"><i class="l"></i><i class="r"></i><i class="u"></i><i class="d"></i></div>
415<div id="throw-debug" class="hidden" aria-hidden="true"></div>
416<section id="intervention-panel" class="hidden" aria-label="Rewrite objective">
417  <div class="intervention-kicker">Rewrite</div>
418  <strong id="intervention-title">Save player</strong>
419  <span id="intervention-copy"></span>
420  <div class="intervention-stats"><span id="intervention-hp">100 HP</span><span id="intervention-threat">Threat</span></div>
421  <button id="intervention-preview" type="button">Replay</button>
422  <button id="intervention-start" type="button">Start</button>
423  <button id="intervention-retry" type="button">Retry</button>
424  <button id="intervention-next" class="hidden" type="button">Next moment</button>
425  <button id="intervention-back-replays" class="hidden" type="button">Back to moments</button>
426  <button id="intervention-exit" type="button">Exit</button>
427</section>
428<section id="death-overlay" class="hidden" aria-label="Rewrite result">
429  
430  <div id="death-icon" class="pres-icon hidden" aria-hidden="true"></div>
431  <strong id="death-title">You died</strong>
432  <span id="death-copy"></span>
433  <div id="death-stats" class="hidden"></div>
434  <div id="death-leaderboard" class="hidden" aria-label="Challenge leaderboard"></div>
435  <div class="death-actions">
436    <button id="death-retry" type="button">Retry</button>
437    
438    <button id="death-hint" class="hidden" type="button">Hint (H)</button>
439    <button id="death-next" class="hidden" type="button">Next moment</button>
440    
441    <span id="death-nextdaily" class="hidden"></span>
442    <button id="death-replays" class="hidden" type="button">Back to moments</button>
443    <button id="death-share" class="hidden" type="button">Challenge a friend</button>
444    <button id="death-exit" type="button">Exit</button>
445  </div>
446  
447  <p id="death-keys" class="hidden"></p>
448</section>
449
450<section id="challenge-splash" class="hidden" aria-label="Moment challenge">
451  <div class="challenge-backdrop" aria-hidden="true"></div>
452  <div class="challenge-card">
453    <div class="challenge-kicker" id="challenge-kicker">Moment challenge</div>
454    
455    <div id="challenge-daily-meta" class="hidden"></div>
456    <h2 id="challenge-title">Loading this moment…</h2>
457    <p id="challenge-context"></p>
458    <div id="challenge-stats" class="hidden"></div>
459    <div id="challenge-board" class="hidden" aria-label="Moment leaderboard"></div>
460    <div class="challenge-actions">
461      <button id="challenge-play" class="hidden" type="button">Play the moment</button>
462      <button id="challenge-back" class="hidden" type="button">Back to Practice</button>
463      <a id="challenge-home" class="hidden" href="/">Go to the homepage</a>
464    </div>
465    <div id="challenge-status" aria-live="polite"></div>
466    <div id="challenge-note" class="hidden"><a href="/">Sign in to post your result</a></div>
467    <div class="challenge-brand">memorin — playable CS2 moments</div>
468  </div>
469</section>
470<div id="help-hint"><b>Mouse1/Mouse2</b> player · <b>Space</b> play · <b>,/.</b> frame · <b>←/→</b> seek · <b>Q/E</b> event · <b>⇧Q/⇧E</b> death · <b>⇧←/⇧→</b> round · <b>R</b> review · <b>F</b> camera · <b>C</b> freecam · <b>Z</b> skip freeze · <b>X</b> x-ray · <b>N</b> trails · <b>G</b> hold nade cam · <b>Tab</b> scores · <b>T</b> map · <b>M</b> radar · <b>H</b> hide<br><span class="hint-note">Playback is integer-tick precision — sub-tick command order isn’t reconstructed.</span></div>
471</div>
472
473<aside id="review-panel" aria-label="Match review">
474  <header class="review-head">
475    <div><strong id="review-title">Match review</strong><span id="review-subtitle"></span></div>
476    <div class="rh-actions">
477      <button id="review-density" type="button" aria-pressed="false" aria-label="Toggle review panel density" title="Collapse to the review lane">⇤</button>
478      <button id="review-close" type="button" aria-label="Close match review">×</button>
479    </div>
480  </header>
481  <nav id="review-tabs" aria-label="Review sections">
482    <button type="button" data-review-tab="summary" class="active">Summary</button>
483    <button type="button" data-review-tab="rounds">Rounds</button>
484    <button type="button" data-review-tab="events">Events</button>
485    <button type="button" data-review-tab="utility">Utility</button>
486  </nav>
487  <div id="review-content"></div>
488  
489  <div id="review-lane" aria-label="Round lane"></div>
490</aside>
491
492<div id="replay-preview-modal" class="hidden" role="dialog" aria-modal="true" aria-labelledby="replay-preview-title">
493  <div class="replay-preview-card">
494    <header>
495      <div>
496        <span>Replay moment</span>
497        <h2 id="replay-preview-title">Rewrite the death</h2>
498      </div>
499      <button id="replay-preview-close" type="button" aria-label="Close replay preview">×</button>
500    </header>
501    <div class="replay-clip-wrap"><video id="replay-preview-video" autoplay muted playsinline></video><span class="replay-clip-crosshair" aria-hidden="true"></span></div>
502    <p id="replay-preview-copy"></p>
503    <footer>
504      <button id="replay-preview-back" type="button">Back to moments</button>
505      <button id="replay-preview-next" type="button">Next moment</button>
506      <button id="replay-preview-start" type="button">Replay moment</button>
507    </footer>
508  </div>
509</div>
510
511<div id="loading-indicator" class="hidden">
512  <span class="spinner" aria-hidden="true"></span>
513  <span class="ld-body">
514    <span id="loading-text" role="status" aria-live="polite">Loading…</span>
515    <span id="loading-bar" class="hidden" aria-hidden="true"><i></i></span>
516  </span>
517  <span id="loading-pct" aria-hidden="true"></span>
518</div>
519<div id="overlay">
520
521  
522  <div class="lp-bg lp-bg-ambient" aria-hidden="true"></div>
523  <div class="lp-bg lp-bg-grid" aria-hidden="true"></div>
524  <div class="lp-bg lp-bg-vignette" aria-hidden="true"></div>
525  <div id="lib-backdrop" aria-hidden="true"></div>
526
527  
528  <aside id="overlay-box" aria-label="Navigation">
529    <div class="rail-top">
530      <button id="nav-home" class="lib-brand" type="button" aria-label="Go to homepage">
531        <img class="lib-brand-logo" src="/assets/brand/mark-128.webp" width="30" height="30" alt="">
532        <div class="lib-brand-text">
533          <div class="lib-brand-name">Memorin</div>
534          <div class="lib-brand-sub" data-i18n="title">Playable CS2 moments</div>
535        </div>
536      </button>
537      <button id="lib-close" type="button" class="lib-close" aria-label="Close menu">×</button>
538    </div>
539
540    
541    <nav class="rail-nav" aria-label="Sections">
542      <a class="rail-link" href="/" data-nav="nav-about">
543        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 11 12 3l9 8"/><path d="M5 10v10h14V10"/></svg>
544        <span>Home</span>
545      </a>
546      
547      <button id="nav-replays" class="rail-link" type="button">
548        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 6h11a4 4 0 0 1 0 8H8"/><path d="M8 10 4 14l4 4"/><path d="M17 17l3 3M20 17l-3 3"/></svg>
549        <span>Moments</span>
550        <i class="rail-tag" aria-hidden="true">PRO</i>
551      </button>
552      <button id="nav-library" class="rail-link" type="button">
553        <svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>
554        <span>Demos</span>
555      </button>
556      <button id="nav-practice" class="rail-link" type="button">
557        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3"/><circle cx="12" cy="12" r="9"/></svg>
558        <span>Practice</span>
559      </button>
560      
561      <a class="rail-link" href="/matches" data-nav="nav-matches">
562        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 4h12v5a6 6 0 0 1-12 0Z"/><path d="M9 20h6M12 15v5"/></svg>
563        <span>Pro matches</span>
564      </a>
565      <a class="rail-link" href="/lab/cstv/" data-nav="nav-cstv">
566        <svg viewBox="0 0 24 24" aria-hidden="true"><rect x="2" y="8" width="20" height="13"/><path d="m7 8 5-5 5 5"/><path d="M12 12v5M9.5 14.5h5"/></svg>
567        <span>CSTV</span>
568      </a>
569      <a class="rail-link" href="/lab/skins/" data-nav="nav-skins">
570        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20.6 13.4 12 22l-9-9V4h9Z"/><circle cx="7.5" cy="7.5" r="1.2"/></svg>
571        <span>Skins</span>
572      </a>
573      <a class="rail-link" href="/lab/maps/" data-nav="nav-maps">
574        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 3 3 6v15l6-3 6 3 6-3V3l-6 3Z"/><path d="M9 3v15M15 6v15"/></svg>
575        <span>Maps</span>
576      </a>
577      
578      <a class="rail-link" href="/lab/lineups/" data-nav="nav-lineups">
579        <svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="14" r="7"/><path d="M8.5 7.5V5h5v2.5M13.5 5.5 18 4l1.5 3"/></svg>
580        <span>Lineups</span>
581      </a>
582      
583      <a class="rail-link" href="/lab/sponsors/" data-nav="nav-sponsors">
584        <svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="6" width="18" height="9" rx="1"/><path d="M7 19h10M12 15v4"/></svg>
585        <span>Sponsors</span>
586      </a>
587    </nav>
588
589    <div class="rail-foot">
590      
591      <div id="account" class="hidden"></div>
592      
593      <div id="rail-signin" class="rail-signin hidden"></div>
594      
595      <div id="rail-usage" class="rail-usage hidden"></div>
596      
597      <div id="rail-pro" class="rail-pro hidden"></div>
598      <div class="rail-foot-row">
599        <select id="language" aria-label="Interface language"><option value="en">English</option><option value="lt">Lietuvių</option></select>
600        <div class="policy-links"><a href="/privacy.html" data-i18n="privacy">Privacy & retention</a> · <a href="/legal.html" data-i18n="legal">Attribution & takedown</a> · <a href="/lab/sponsors/" data-nav="nav-sponsors" data-i18n="sponsors">Sponsors</a></div>
601      </div>
602    </div>
603  </aside>
604
605  
606  <div id="account-modal" class="hidden" role="dialog" aria-modal="true" aria-label="Account settings">
607    <div class="account-card">
608      <header class="account-card-head">
609        <h2>Account</h2>
610        <button id="account-close" type="button" class="account-close" aria-label="Close account settings">×</button>
611      </header>
612      <div id="account-detail"></div>
613      
614
615    </div>
616  </div>
617
618  
619
620  
621
622  
623  <div id="landing" class="booting">
624    
625    <div id="dash-omni">
626      
627      <button id="nav-open-lib" type="button" class="dash-burger" aria-label="Open menu" aria-controls="overlay-box" aria-expanded="false">
628        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><path d="M3 6h18M3 12h18M3 18h18"/></svg>
629      </button>
630      <form id="instant-watch" class="instant" autocomplete="off">
631        <input id="instant-input" type="text" inputmode="url" spellcheck="false"
632               placeholder="Paste a match link, share code, or demo link"
633               aria-label="Paste a match link, share code, or demo link">
634        <button id="instant-go" class="btn-take" type="submit">Watch it</button>
635      </form>
636      <button id="nav-upload" class="omni-more" type="button" title="Drop a demo file, or connect your match history">
637        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M21 15v4H3v-4M12 3v12M7 10l5 5 5-5"/></svg>
638        <span>Import</span>
639      </button>
640      
641      <a id="omni-signin" class="omni-more hidden" href="/auth/steam">
642        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><path d="M15 3h4v18h-4M10 17l5-5-5-5M15 12H3"/></svg>
643        <span>Sign in</span>
644      </a>
645      <p id="instant-note" class="instant-note" aria-live="polite"></p>
646    </div>
647    <header class="dash-head">
648      <div class="dash-title">
649        
650        <h1>Memorin — CS2 demo viewer in 3D, with moments you can play</h1>
651        <p class="dash-sub">Watch any Counter-Strike 2 demo in full 3D in your browser, then take over the round that lost it and play it yourself.</p>
652      </div>
653      <div class="dash-actions">
654        <button id="overlay-close" class="hidden" type="button">← Return to lab</button>
655        <div id="overlay-actions">
656          <button id="overlay-upload" class="hidden" type="button" data-i18n="upload">Upload .dem</button>
657        </div>
658      </div>
659    </header>
660
661    <div id="overlay-status" class="dash-status hidden">Loading…</div>
662    <button id="upload-cancel" class="hidden" type="button">Cancel upload</button>
663    <div id="login-gate" class="hidden"></div>
664
665    
666    <section id="sec-library" class="dash-section hidden">
667      <div class="lib-toolbar">
668        <div class="lib-search">
669          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>
670          <input id="lib-search" type="search" placeholder="Search matches and maps…" autocomplete="off" spellcheck="false" aria-label="Search matches">
671        </div>
672        <div class="lib-tabs" role="group" aria-label="Filter matches">
673          <button class="lib-tab is-active" type="button" data-filter="all">All</button>
674          <button class="lib-tab" type="button" data-filter="ready">Ready</button>
675          <button class="lib-tab" type="button" data-filter="working">Processing</button>
676        </div>
677      </div>
678
679      
680      <section id="sec-import" class="import-panel hidden" aria-labelledby="import-title">
681        <button id="import-close" class="import-close" type="button" aria-label="Close import panel">×</button>
682        <h2 id="import-title" class="sec-title">Add a demo</h2>
683        <p class="sec-sub">Drop the file and we unpack it, parse it, and build the replay while you do something else. Got a match link or a share code instead? Paste it in the bar at the top.</p>
684        <div id="import-status" class="import-status" aria-live="polite"></div>
685        
686        <div id="overlay-add" class="hidden">
687          <input id="add-input" type="text" placeholder="Paste a match link, share code, or demo link" autocomplete="off" spellcheck="false">
688          <button id="add-btn" type="button">Watch in 3D</button>
689        </div>
690        <div id="series-picker" class="series-picker hidden" aria-live="polite"></div>
691        <div id="import-drop" class="import-drop" role="button" tabindex="0" aria-label="Choose or drop a demo file">
692          <div class="import-drop-main"><strong>Drop a demo file</strong> — or click to choose one</div>
693          <div class="import-drop-sub">.dem, .dem.gz, .dem.zst — straight from a FACEIT download, no unzipping</div>
694          <button id="import-upload" type="button">Choose a file</button>
695        </div>
696        <div id="overlay-connect" class="hidden">
697          <div class="connect-title">Set &amp; forget: auto-import your matchmaking games</div>
698          <div class="connect-row">
699            <input id="auth-input" type="text" placeholder="Match-history authentication code" autocomplete="off" spellcheck="false">
700            <input id="seed-input" type="text" placeholder="One recent share code (CSGO-…)" autocomplete="off" spellcheck="false">
701            <button id="connect-btn" type="button">Connect</button>
702          </div>
703          <div class="connect-hint">One-time setup. Auth code: Steam → CS2 → “Access to Your Match History”. Share code: in CS2 → Watch → Your Matches → Copy Share Code. Valve’s API has no “list all”, so it needs one share code to start from; after that new matches import automatically (an older one backfills more history).</div>
704        </div>
705        <div class="import-ext-hint">Use a supported match site? Add a one-click <strong>WATCH IN 3D</strong> button to your matchroom with the Chrome &amp; Firefox extension.</div>
706      </section>
707
708      
709      <section id="lib-resume" class="lib-resume hidden" aria-label="Continue watching"></section>
710
711      <div class="lib-group">
712        <h3 class="lib-h" id="lib-ready-h">Recent matches</h3>
713        <div id="overlay-list" class="match-list"></div>
714      </div>
715
716      <div class="lib-group hidden" id="lib-working">
717        <h3 class="lib-h">Processing <span class="lib-count" id="lib-working-count"></span></h3>
718        <div id="lib-working-list" class="match-list"></div>
719        <p class="lib-note">Parsing indexes every player snapshot, event and grenade. You will be able to watch these as soon as they finish.</p>
720      </div>
721
722      <button id="upload-tile" class="demo-card demo-card--upload" type="button">
723        <span class="upload-tile-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M12 16V4M7 9l5-5 5 5M4 18v2h16v-2"/></svg></span>
724        <span class="upload-tile-text">
725          <span class="upload-tile-title">Drop your <b>.dem</b> here</span>
726          <span class="upload-tile-sub">or click to browse · parsed in seconds</span>
727          
728          <span id="overlay-drop" class="upload-tile-sub" data-i18n="drop">.dem, .dem.gz or .dem.zst · you can also drop it anywhere on this page</span>
729        </span>
730      </button>
731    </section>
732
733    
734    <section id="sec-match-feed" class="dash-section hidden" aria-live="polite"></section>
735
736    
737    <section id="sec-cstv" class="dash-section hidden">
738      <div class="lib-group" id="cstv-live-zone">
739        <h3 class="lib-h">Live matches <span class="lib-count cstv-tag">in progress</span></h3>
740        <div class="cstv-live">
741          <p><b>The live path is built and it runs.</b> A real 2026 professional match already plays through the
742            genuine live pipeline at wall-clock cadence — you can pause it mid-round, fly the camera, rewind inside
743            the stream and jump back to the edge. That is shipped code, not a plan.</p>
744          <p><b>What is missing is a broadcast feed we are permitted to consume.</b> CSTV rides Counter-Strike 2's
745            HTTP broadcast protocol, and we can parse one today at parity with a finished demo, from the first tick. We do not have an
746            authorised relay to point it at. That is an access question, not an engineering one, and we will not put
747            a date on an answer we do not have.</p>
748          <p><b>Live will never mean instant.</b> A CSTV broadcast is held back about 105 seconds by its own source.
749            That is Valve's anti-ghosting delay — the same wall clock as the in-game Watch tab — so live here will
750            arrive 105 seconds behind the server, with the measured delay printed on screen. Never faster.</p>
751          <p>Until a feed exists, nothing on this page is a game being played right now. When a demonstration of the
752            live experience is running against a finished match, it is labelled as a replay and shows up on the
753            <a href="/matches">
753public match wall</a> — never here, dressed as something it is not.</p>
754        </div>
755      </div>
756    </section>
757
758    <section id="sec-replays" class="dash-section hidden">
759      <div id="replays-status" class="dash-status">Loading moments...</div>
760      <article id="replay-inline-preview" class="replay-inline-preview hidden" aria-live="polite">
761        <div class="replay-clip-wrap"><video id="replay-inline-video" autoplay muted playsinline></video><span class="replay-clip-crosshair" aria-hidden="true"></span><span id="replay-inline-preparing" class="replay-clip-preparing hidden" role="status"><i aria-hidden="true"></i><b>Preparing smooth playback…</b></span></div>
762        <div class="replay-inline-copy">
763          <span>Selected moment</span>
764          <h3 id="replay-inline-title">Replay moment</h3>
765          <p id="replay-inline-text"></p>
766          <div class="replay-inline-actions">
767            <button id="replay-inline-close" type="button">Close clip</button>
768            <button id="replay-inline-start" type="button">Replay this moment</button>
769          </div>
770        </div>
771      </article>
772      <div id="replay-index" class="replay-index" aria-live="polite"></div>
773    </section>
774
775    
776    <section id="sec-practice" class="dash-section practice-hud hidden">
777      
778      <div id="practice-rank" class="practice-rank" aria-live="polite"></div>
779
780      <div class="practice-board">
781        <div class="practice-board-main">
782          
783          <div id="practice-hero" class="practice-hero" aria-live="polite">
784            <div class="phd-scrim" aria-hidden="true"></div>
785            <div class="phd-hero-row">
786              <div class="phd-hero-copy">
787                <div class="phd-chips">
788                  <span id="practice-hero-chip" class="phd-chip-next">Up next</span>
789                  <span id="practice-hero-diff" class="rmc-diff" hidden></span>
790                </div>
791                <h2 id="practice-hero-title" class="phd-hero-title">Play a real moment</h2>
792                <p id="practice-hero-sub" class="phd-hero-sub">Watch it, take control, change the outcome.</p>
793                
794                <div id="practice-picker" class="practice-picker" role="group" aria-label="Practice"></div>
795              </div>
796              
797              <article id="practice-session" class="phd-hero-ring" aria-live="polite">
798                <div class="pcs-ring" id="practice-session-ring">
799                  <strong id="practice-session-count">0 / 3</strong>
800                  <span id="practice-session-unit">Free today</span>
801                </div>
802                <p id="practice-session-copy" class="phd-ring-note">Retries don’t count</p>
803              </article>
804            </div>
805          </div>
806
807          
808          <section id="practice-results" class="practice-results hidden" aria-live="polite"></section>
809
810          
811          <section class="practice-drills" aria-labelledby="practice-drills-title">
812            <h2 id="practice-drills-title" class="practice-cat-head sr-only">Recommended drills</h2>
813            <div id="practice-categories" class="practice-categories" aria-live="polite"></div>
814          </section>
815
816          
817          <div id="practice-stats" class="practice-stats" aria-live="polite"></div>
818        </div>
819
820        
821        <aside id="practice-pro-card" class="practice-pro-card">
822          <div class="ppc-head">
823            <div class="ppc-kicker ppc-kicker--pro">Memorin PRO</div>
824            <h3 class="ppc-title">Practice<br>without limits</h3>
825            <p class="ppc-body">Three moments a day is the free ration. PRO is the whole library, every day.</p>
826          </div>
827          
828          <ul class="ppc-list" id="practice-pro-list"></ul>
829          <div class="ppc-foot">
830            <div class="ppc-price"><b id="practice-pro-price">€9,99</b><span id="practice-pro-unit">/ month</span></div>
831            <div id="practice-pro-yearly" class="ppc-yearly"><del id="practice-pro-yearly-regular">€119,88 / year</del><span aria-hidden="true"> → </span><b id="practice-pro-yearly-price">€69,99 / year</b><em id="practice-pro-yearly-saving">save €49,89 (42%)</em></div>
832            <button id="practice-pro-action" type="button" class="ppc-btn ppc-btn--pro" data-pro>Upgrade to PRO</button>
833            <p id="practice-pro-state" class="ppc-fine">Cancel any time · keeps your rating</p>
834          </div>
835        </aside>
836      </div>
837
838      
839      <div id="practice-daily" class="practice-daily practice-tile" data-mode="daily" aria-hidden="true"></div>
840      
841    </section>
842
843    <section id="sec-skins" class="dash-section skin-section hidden" aria-label="Skin viewer">
844      <div class="skin-head">
845        <div id="skin-provenance" class="skin-provenance" aria-live="polite">Loading current CS2 catalog…</div>
846      </div>
847
848      
849      <div class="skin-lab-shell" aria-label="Memorin finish workbench">
850        <div class="skin-lab-stage">
851          <canvas id="skin-lab-canvas" aria-label="Interactive CS2 skin preview"></canvas>
852          <div id="skin-lab-status" class="skin-lab-status" aria-live="polite">Choose a finish to start the viewer.</div>
853          <div class="skin-stage-mark" aria-hidden="true">
854            <span>Memorin finish lab</span>
855            <strong>Live viewmodel</strong>
856          </div>
857          
858          <button id="skin-show-ui" class="skin-show-ui hidden" type="button">Show UI</button>
859        </div>
860
861        <div class="skin-hud">
862            
863            <article id="skin-selection" class="skin-plate hidden" aria-live="polite">
864              <span id="skin-selection-weapon" class="skin-selection-weapon"></span>
865              <h3 id="skin-selection-name"></h3>
866            </article>
867
868            <div class="skin-deck">
869              <div class="skin-deck-rail">
870                <div class="skin-deck-group skin-deck-modes">
871                  <div class="skin-lab-view-tabs" role="group" aria-label="Inspection mode">
872                    <button type="button" class="is-active" data-skin-view="front">
873                      <span class="skin-mode-name">First person</span>
874                      <span class="skin-mode-hint">Arms + gun</span>
875                    </button>
876                    <button type="button" data-skin-view="standalone">
877                      <span class="skin-mode-name">Standalone</span>
878                      <span class="skin-mode-hint">Drag to turn</span>
879                    </button>
880                  </div>
881                </div>
882
883                <div class="skin-deck-group skin-deck-fp">
884                  <div class="skin-lab-side" role="group" aria-label="Agent side">
885                    <button id="skin-lab-ct" class="is-active" type="button">CT</button>
886                    <button id="skin-lab-t" type="button">T</button>
887                  </div>
888                  <div class="skin-lab-actions" role="group" aria-label="Viewmodel actions">
889                    <button id="skin-lab-shoot" type="button"><kbd>LM</kbd><span>Shoot</span></button>
890                    <button id="skin-lab-reload" type="button"><kbd>R</kbd><span>Reload</span></button>
891                    <button id="skin-lab-inspect" type="button"><kbd>F</kbd><span>Inspect</span></button>
892                    <button id="skin-lab-draw" type="button"><kbd>G</kbd><span>Draw</span></button>
893                  </div>
894                </div>
895
896                <div class="skin-deck-group skin-deck-orbit">
897                  <span class="skin-orbit-hint">Drag to turn · scroll to zoom</span>
898                  <button id="skin-orbit-reset" type="button" class="skin-deck-btn">Recentre</button>
899                </div>
900
901                <div class="skin-deck-group skin-deck-pops">
902                  <button id="skin-pop-finish-btn" class="skin-deck-btn" type="button" aria-expanded="false" aria-controls="skin-pop-finish">Finish</button>
903                  <button id="skin-pop-studio-btn" class="skin-deck-btn" type="button" aria-expanded="false" aria-controls="skin-pop-studio">Studio</button>
904                  <button id="skin-default" class="skin-deck-btn" type="button">Stock</button>
905                  <button id="skin-hide-ui" class="skin-deck-btn skin-hide-btn" type="button" aria-pressed="false" title="Hide the viewer controls (Esc or click to restore)">Hide UI</button>
906                </div>
907              </div>
908
909              
910              <div id="skin-pop-finish" class="skin-pop hidden" role="group" aria-label="Finish parameters">
911                <label class="skin-param" for="skin-wear"><span>Wear</span><output id="skin-wear-value"></output><input id="skin-wear" type="range" step="0.000001"></label>
912                <label class="skin-param skin-param-seed" for="skin-seed"><span>Pattern seed</span><input id="skin-seed" type="number" min="0" max="4294967295" step="1" inputmode="numeric"></label>
913              </div>
914
915              <div id="skin-pop-studio" class="skin-pop hidden" role="group" aria-label="Studio look">
916                <div class="skin-studio-head"><strong>Studio look</strong><button id="skin-studio-reset" type="button">Reset</button></div>
917                <label class="skin-param" for="skin-brightness"><span>Brightness</span><output id="skin-brightness-value"></output><input id="skin-brightness" type="range" min="0.6" max="1.6" step="0.01" value="1.05"></label>
918                <label class="skin-param" for="skin-reflections"><span>Reflections</span><output id="skin-reflections-value"></output><input id="skin-reflections" type="range" min="0" max="2.2" step="0.01" value="1.25"></label>
919                <label class="skin-param" for="skin-vibrance"><span>Vibrance</span><output id="skin-vibrance-value"></output><input id="skin-vibrance" type="range" min="0.4" max="1.8" step="0.01" value="1"></label>
920                <div class="skin-bg-row">
921                  <label class="skin-bg-color" for="skin-bg-color"><span>
921Background</span><input id="skin-bg-color" type="color" value="#071126"></label>
922                  <label class="skin-bg-image" role="button" tabindex="0"><span>Attach image</span><input id="skin-bg-image" type="file" accept="image/*"></label>
923                  <button id="skin-bg-clear" type="button">Clear image</button>
924                </div>
925              </div>
926            </div>
927        </div>
928      </div>
929
930      <details class="skin-catalog-drawer" open>
931        <summary><span>Finish library</span><small>Every finish comes from the current CS2 catalog. Equip CT and T finishes separately in Play CS2.</small></summary>
932        <div class="skin-browser-layout">
933          <aside class="skin-weapons" aria-label="Weapons">
934            <label class="skin-search-label" for="skin-weapon-search">Find a weapon</label>
935            <input id="skin-weapon-search" class="skin-search" type="search" autocomplete="off" placeholder="AK-47, AWP, knife…">
936            <div id="skin-weapon-list" class="skin-weapon-list" role="listbox" aria-label="Current CS2 weapons"></div>
937          </aside>
938
939          <div class="skin-finishes">
940            <div class="skin-toolbar">
941              <label class="skin-search-label" for="skin-finish-search">Find a finish</label>
942              <input id="skin-finish-search" class="skin-search" type="search" autocomplete="off" placeholder="Doppler, Fade, Printstream…">
943              <label class="skin-search-label" for="skin-rarity">Rarity</label>
944              <select id="skin-rarity" class="skin-filter">
945                <option value="">All rarities</option>
946              </select>
947            </div>
948            <div id="skin-empty" class="skin-empty hidden">No current-CS2 finishes match those filters.</div>
949            <div id="skin-finish-grid" class="skin-finish-grid" role="listbox" aria-label="Compatible finishes"></div>
950            <button id="skin-load-more" class="skin-load-more hidden" type="button">Show more finishes</button>
951          </div>
952        </div>
953      </details>
954    </section>
955
956    <section id="sec-maps" class="dash-section hidden">
957      <div id="map-grid" class="demo-grid"></div>
958    </section>
959
960    
961    <section id="sec-lineups" class="dash-section hidden"></section>
962
963    
964    <section id="sec-matches" class="dash-section hidden"></section>
965
966    
967    <section id="sec-kit" class="dash-section hidden"></section>
968
969    
970    <section id="sec-play" class="dash-section cs2menu hidden" aria-label="Play CS2">
971      <div class="cs2menu-bg" aria-hidden="true"></div>
972
973      <header class="cs2topbar">
974        <button id="cs2-burger" class="cs2burger" type="button" aria-label="Open menu">
975          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><path d="M3 6h18M3 12h18M3 18h18"/></svg>
976        </button>
977        <div class="cs2topbar-icons" aria-hidden="true">
978          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M3 11l9-7 9 7M5 10v10h14V10"/></svg>
979          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><rect x="3" y="5" width="18" height="13" rx="1.5"/><path d="M8 21h8"/></svg>
980          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><circle cx="12" cy="12" r="3"/><path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M18.4 5.6l-2.1 2.1M7.7 16.3l-2.1 2.1"/></svg>
981          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M12 3v9M7 6a8 8 0 1 0 10 0"/></svg>
982        </div>
983        <nav class="cs2tabs" aria-label="CS2 menu">
984          <button id="cs2-tab-inventory" class="cs2tab" type="button">Inventory</button>
985          <button id="cs2-tab-loadout" class="cs2tab" type="button">Loadout</button>
986          <button id="cs2-tab-play" class="cs2tab is-active" type="button" aria-expanded="false">Play</button>
987          <button class="cs2tab" type="button" disabled aria-disabled="true" title="Coming soon">Store</button>
988          <button class="cs2tab" type="button" disabled aria-disabled="true" title="Coming soon">News</button>
989        </nav>
990        <div class="cs2topbar-right" aria-hidden="true"><span class="cs2avatar"></span></div>
991      </header>
992
993      
994      <div id="cs2-home" class="cs2home">
995        <canvas id="cs2-agent" class="cs2home-agent" aria-hidden="true"></canvas>
996        <div class="cs2home-hint">Select <b>PLAY</b> to choose a mode</div>
997      </div>
998
999      
1000      <div id="cs2-inventory" class="cs2inventory hidden">
1001        <div class="cs2inventory-toolbar">
1002          <div><strong>Inventory</strong><span id="cs2-inventory-source">Sign in through Steam to load your owned CS2 items.</span></div>
1003          <label><span>Search</span><input id="cs2-inventory-search" type="search" autocomplete="off" placeholder="Weapon, finish, sticker, case…"></label>
1004          <label><span>Type</span><select id="cs2-inventory-filter"><option value="">All items</option></select></label>
1005          <button id="cs2-inventory-refresh" type="button">Refresh</button>
1006        </div>
1007        <div id="cs2-inventory-status" class="cs2inventory-status" aria-live="polite"></div>
1008        <div id="cs2-inventory-grid" class="cs2inventory-grid" role="list" aria-label="Owned Steam inventory"></div>
1009        <button id="cs2-inventory-more" class="cs2inventory-more hidden" type="button">Load more owned items</button>
1010        <aside id="cs2-inventory-detail" class="cs2inventory-detail hidden" aria-live="polite"></aside>
1011      </div>
1012
1013      
1014      <div id="cs2-loadout" class="cs2loadout hidden">
1015        <div class="cs2loadout-head">
1016          <div class="cs2loadout-side-tabs" role="tablist" aria-label="Loadout side">
1017            <button id="cs2-loadout-ct" class="is-active" type="button" role="tab" aria-selected="true">Equip CT</button>
1018            <button id="cs2-loadout-t" type="button" role="tab" aria-selected="false">Equip T</button>
1019          </div>
1020          <div><strong id="cs2-loadout-title">Counter-Terrorist loadout</strong><span id="cs2-loadout-source">Loading current CS2 slots…</span></div>
1021        </div>
1022        <div class="cs2loadout-body">
1023          <aside id="cs2-loadout-utility" class="cs2loadout-utility" aria-label="Equipment and melee"></aside>
1024          <div id="cs2-loadout-grid" class="cs2loadout-grid" aria-live="polite"></div>
1025        </div>
1026        <div id="cs2-loadout-picker" class="cs2loadout-picker hidden" role="dialog" aria-modal="true" aria-labelledby="cs2-loadout-picker-title">
1027          <button id="cs2-loadout-picker-close" class="cs2loadout-picker-close" type="button" aria-label="Close loadout picker">×</button>
1028          <span id="cs2-loadout-picker-slot"></span>
1029          <h3 id="cs2-loadout-picker-title">Choose equipment</h3>
1030          <div id="cs2-loadout-weapons" class="cs2loadout-weapons"></div>
1031          <div class="cs2loadout-picker-tools">
1032            <label><span>Find a finish</span><input id="cs2-loadout-finish-search" type="search" autocomplete="off" placeholder="Search current CS2 finishes"></label>
1033            <button id="cs2-loadout-stock" type="button">Use stock finish</button>
1034          </div>
1035          <div id="cs2-loadout-finishes" class="cs2loadout-finishes"></div>
1036        </div>
1037      </div>
1038
1039      
1040      <div id="cs2-play" class="cs2play hidden">
1041        <div class="cs2play-modes" role="tablist" aria-label="Game mode">
1042          <button class="cs2mode" type="button" disabled aria-disabled="true">Premier</button>
1043          <button class="cs2mode" type="button" disabled aria-disabled="true">Competitive</button>
1044          <button class="cs2mode" type="button" disabled aria-disabled="true">Wingman</button>
1045          <button class="cs2mode" type="button" disabled aria-disabled="true">Casual</button>
1046          <button id="cs2-mode-dm" class="cs2mode is-active" type="button" role="tab" aria-selected="true">Deathmatch</button>
1047          <button class="cs2mode" type="button" disabled aria-disabled="true">Private</button>
1048        </div>
1049
1050        <div id="cs2-maps" class="cs2play-maps" role="listbox" aria-label="Map">
1051          
1052          <button id="cs2-map-mirage" class="cs2map is-active" type="button" data-map="de_mirage" role="option" aria-selected="true">
1053            <span class="cs2map-art"></span>
1054            <span class="cs2map-fade"></span>
1055            <span class="cs2map-badge">DM</span>
1056            <span class="cs2map-name">Mirage</span>
1057            <span class="cs2map-status" id="cs2-mirage-status">Ready</span>
1058          </button>
1059        </div>
1060
1061        
1062        <div id="cs2-server-panel" class="cs2server">
1063          <div id="mp-banner" class="mp-banner hidden"></div>
1064          <div class="cs2server-create">
1065            <label class="mp-private hidden" id="mp-private-wrap"><input type="checkbox" id="mp-private"> Private</label>
1066            <input id="mp-private-password" class="mp-private-password hidden" type="password" autocomplete="off" minlength="4" maxlength="64" placeholder="Lobby password" aria-label="Private lobby password">
1067            <button id="mp-host" type="button" class="mp-btn">Create room</button>
1068            <button id="mp-solo" type="button" class="mp-btn mp-btn-ghost" title="Practice offline against bots — no server is created">Play solo</button>
1069          </div>
1070          <div class="mp-list-head"><span>Open matches</span><button id="mp-refresh" type="button" class="mp-refresh" aria-label="Refresh open matches">↻</button></div>
1071          <div id="mp-list" class="mp-list"></div>
1072        </div>
1073      </div>
1074    </section>
1075
1076    <section id="sec-about" class="dash-section dash-about">
1077
1078    
1079    <section class="hero">
1080      
1081      <div class="hero-scene" aria-hidden="true">
1082        <video id="hero-video" poster="/assets/landing/hero-poster.jpg"
1083               autoplay muted loop playsinline preload="metadata" disablepictureinpicture>
1084          <source src="/assets/landing/hero.webm" type="video/webm">
1085          <source src="/assets/landing/hero.mp4" type="video/mp4">
1086        </video>
1087        <span class="hero-veil"></span>
1088      </div>
1089
1090      <div class="hero-inner">
1091        
1092        <p class="readout" id="hero-readout">
1093          <span class="rd-live" aria-hidden="true"></span>
1094          <span class="rd-label">Today’s moment</span>
1095        </p>
1096
1097        
1098        <h2 class="hero-h">Watch any CS2 demo in 3D.<br>Then play the round that lost it.</h2>
1099
1100        
1101        <dl class="hero-card">
1102          <div class="hc-cell hc-cell--duel">
1103            <dt>The moment</dt>
1104            <dd id="hero-situation"></dd>
1105          </div>
1106          <div class="hc-cell">
1107            <dt>Map</dt>
1108            <dd id="hero-map"></dd>
1109          </div>
1110          <div class="hc-cell">
1111            <dt>Tried by</dt>
1112            <dd id="hero-attempts"></dd>
1113          </div>
1114        </dl>
1115
1116        
1117        <div class="hero-cta">
1118          <button id="hero-take-over" class="btn-take" type="button">Play daily</button>
1119          <button id="hero-watch" class="btn-quiet" type="button">Open the 3D demo viewer</button>
1120        </div>
1121        <p id="hero-daily-clock" class="hero-clock" aria-live="off">New daily in <span id="hero-daily-countdown"></span></p>
1122
1123        
1124        <p class="hero-sub">no download · no account · runs in this tab</p>
1125      </div>
1126    </section>
1127
1128    
1129    <div class="proof-band">
1130      <ul class="proof" aria-label="What runs in the browser">
1131        <li>
1132          <svg class="proof-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.65" aria-hidden="true"><path d="m12 3 7 4v10l-7 4-7-4V7Z"/><path d="m12 7 3 2v6l-3 2-3-2V9Z"/></svg>
1133          <span class="proof-copy"><strong>10 maps</strong><span>Real CS2 maps</span></span>
1134        </li>
1135        <li>
1136          <svg class="proof-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.65" aria-hidden="true"><circle cx="12" cy="12" r="8"/><path d="M8 13v-2a4 4 0 0 1 8 0v2M8 13h2v4H8zM14 13h2v4h-2z"/></svg>
1137          <span class="proof-copy"><strong>Every POV</strong><span>Any player, any round</span></span>
1138        </li>
1139        <li>
1140          <svg class="proof-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.65" aria-hidden="true"><path d="M8 4h8v4l2 2v9H6v-9l2-2Z"/><path d="M9 12h6M9 15h6"/></svg>
1141          <span class="proof-copy"><strong>Real physics</strong><span>Grenades, smoke &amp; recoil</span></span>
1142        </li>
1143        <li>
1144          <svg class="proof-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.65" aria-hidden="true"><path d="M9 4a7 7 0 1 0 7 7"/><path d="M15 4h5v5M20 4l-7 7"/><path d="M8 13h4v4H8z"/></svg>
1145          <span class="proof-copy"><strong>No install</strong><span>Runs in your browser</span></span>
1146        </li>
1147      </ul>
1148    </div>
1149
1150    
1151    <a class="pro-band" href="/matches"><strong>Watch pro matches in 3D</strong><span>Every round, every POV. No account needed.</span></a>
1152
1153    
1154
1155    
1156    <div id="home-in" class="home-state hidden">
1157
1158      <section class="hs-block" aria-labelledby="hs-resume-h">
1159        <div class="hs-head">
1160          <h2 id="hs-resume-h" class="hs-h">Pick up where you left off</h2>
1161          <a class="hs-more" href="/lab/demos/" data-nav="nav-library">All demos</a>
1162        </div>
1163        
1164        <div id="home-continue" class="hs-cards"></div>
1165      </section>
1166
1167      <section class="hs-block" aria-labelledby="hs-moment-h">
1168        <div class="hs-head">
1169          <h2 id="hs-moment-h" class="hs-h">Today's moment</h2>
1170          
1171          <span class="hs-stamp">Resets in <span id="home-daily-countdown"></span></span>
1172        </div>
1173        <div class="hs-moment">
1174          <div id="home-moment-shot" class="hsm-shot">
1175            <p id="home-moment-ctx" class="hsm-ctx">Today’s moment</p>
1176            <p id="home-moment-title" class="hsm-h">today’s moment</p>
1177            <p id="home-moment-sub" class="hsm-sub">Same position, same utility, same clock.</p>
1178            <div class="hsm-act">
1179              <button id="home-moment-play" class="hsm-play" type="button">Play it</button>
1180              <button id="home-moment-watch" class="hsm-link" type="button">Watch what happened</button>
1181            </div>
1182          </div>
1183          
1184          <div class="hsm-board">
1185            <div class="hsb-head">
1186              <span class="hsb-t">Who rewrote it</span>
1187              <span id="home-board-count" class="hsb-n"></span>
1188            </div>
1189            <div id="home-board-rows" class="hsb-rows"></div>
1190            <div class="hsb-streak">
1191              <div class="hsb-streak-head">
1192                <span>Your streak</span><b id="home-streak-days">—</b>
1193              </div>
1194              <div id="home-streak-bar" class="hsb-streak-bar" aria-hidden="true"></div>
1195            </div>
1196          </div>
1197        </div>
1198      </section>
1199
1200      <section class="hs-block" aria-label="Your week">
1201        <div id="home-week" class="hs-week"></div>
1202      </section>
1203
1204      
1205      <div id="home-plan" class="hs-plan hidden"></div>
1206    </div>
1207
1208    
1209    <div id="home-out" class="home-state">
1210
1211      <section class="hs-block hs-pitch" aria-labelledby="hs-pitch-h">
1212        <h2 id="hs-pitch-h" class="hs-h2">See what happened. Then change it.</h2>
1213        
1214        <div class="hs-two">
1215          <a class="hs-panel" href="/demo-viewer/" data-nav="nav-library">
1216            <span class="hs-shot">
1217              <img src="/assets/landing/card-watch.jpg" width="1120" height="630"
1218                alt="The 3D Demo Viewer showing a Dust2 round: volumetric smoke, both team rosters, killfeed, radar and a replay timeline."
1219                loading="lazy" decoding="async">
1220              <span class="hs-tag">01</span>
1221            </span>
1222            <strong class="hs-panel-h">Watch the match</strong>
1223            <span class="hs-panel-p">Paste a link. Every round, every player’s POV, every grenade — on the real map, in this tab.</span>
1224            <span class="hs-panel-cta">Open the viewer</span>
1225          </a>
1226          
1227          <a id="home-pitch-play" class="hs-panel" href="/replay-moments/">
1228            <span class="hs-shot">
1229              <img src="/assets/landing/card-moment.jpg" width="1120" height="630"
1230                alt="First-person view inside a Replay Moment, holding a USP-S with the CS2 HUD showing health, armour and ammo."
1231                loading="lazy" decoding="async">
1232              <span class="hs-tag">02</span>
1233            </span>
1234            <strong class="hs-panel-h">Play the death</strong>
1235            <span class="hs-panel-p">Same positions, same utility, your hands. A new one every day — no account needed to try it.</span>
1236            <span class="hs-panel-cta">Play today’s moment</span>
1237          </a>
1238        </div>
1239      </section>
1240
1241      
1242      <nav class="hs-block hs-tools" aria-label="More in Memorin">
1243        <a href="/lab/practice/" data-nav="nav-practice"><strong>Practice</strong><span>Improve decisions</span></a>
1244        <a href="/deathmatch/" data-nav="nav-play"><strong>Deathmatch</strong><span>Warm up aim</span></a>
1245        <a href="/skin-viewer/" data-nav="nav-skins"><strong>Skin Viewer</strong><span>Inspect in first person</span></a>
1246        <a href="/lab/maps/" data-nav="nav-maps"><strong>Maps</strong><span>Walk them empty</span></a>
1247      </nav>
1248
1249      
1250      
1251
1252      
1253      <div class="hs-block">
1254        <div class="hs-steam">
1255          <div class="hs-steam-copy">
1256            <p class="hs-steam-h">Sign in with Steam to keep your demos</p>
1257            <p id="home-steam-sub" class="hs-steam-p">Free: 1 demo a day, kept 2 days, 1 moment from each of your matches and 3 practice moments a day. PRO removes the limits.</p>
1258          </div>
1259          <a class="hs-steam-btn" href="/auth/steam">
1260            <span class="hs-steam-mark" aria-hidden="true"></span>
1261            <span><span class="hs-steam-kicker">Sign in through</span><span class="hs-steam-word">Steam</span></span>
1262          </a>
1263        </div>
1264      </div>
1265
1266      
1267      <section class="hs-block hs-qa" aria-labelledby="hs-qa-h">
1268        <h2 id="hs-qa-h" class="hs-h">Questions</h2>
1269        <div class="hs-qa-grid">
1270          <div class="hs-qa-item">
1271            <p class="hs-q">Can I watch CS2 demos in the browser?</p>
1272            <p class="hs-a">Yes. Upload a Counter-Strike 2 .dem file to Memorin and it becomes a full 3D browser replay with real map geometry, player movement, utility, HUD, POV, follow and free-camera controls. See the <a href="/demo-viewer/">CS2 demo viewer online</a>, a <a href="/2d-demo-viewer/">2D radar replay</a>, or the <a href="/blog/best-cs2-demo-viewer.html">best CS2 demo viewer</a> compared.</p>
1273          </div>
1274          <div class="hs-qa-item">
1275            <p class="hs-q">What is a Replay Moment?</p>
1276            <p class="hs-a">A Replay Moment is a real situation from a real match that you can play yourself. Memorin rebuilds the positions, utility, health and clock, then hands you control so you can try a different decision.</p>
1277          </div>
1278          <div class="hs-qa-item">
1279            <p class="hs-q">Is Memorin free?</p>
1280            <p class="hs-a">Playing the daily moment needs no account at all. A free signed-in account watches demos, uses match review, and adds one demo a day — uploaded or imported, either counts. Free demos are kept on the server for 48 hours, and your browser saves its own copy so the match stays watchable after that. PRO adds the full Rematch report on every match, every moment from your own matches, creating and sharing your own moments, unlimited practice, unlimited demos with 30-day storage, and the advanced demo controls.</p>
1281          </div>
1282          <div class="hs-qa-item">
1283            <p class="hs-q">Are uploaded CS2 demos private?</p>
1284            <p class="hs-a">Private demos and parsed replay data are available only to the account that uploaded them. Memorin retains private demos and derived caches for 30 days on PRO and 48 hours on the free tier, and account controls let users delete individual demos or their account. <a href="/privacy.html">Read the privacy and retention policy.</a></p>
1285          </div>
1286          <div class="hs-qa-item">
1287            <p class="hs-q">Is Memorin affiliated with Valve?</p>
1288            <p class="hs-a">No. Memorin is not affiliated with or endorsed by Valve. Counter-Strike 2 is a trademark of Valve Corporation.</p>
1289          </div>
1290        </div>
1291      </section>
1292    </div>
1293    </section>
1294
1295    <footer class="foot">
1296      <div class="foot-brand">
1297        <img class="foot-logo" src="/assets/brand/mark-128.webp" width="26" height="26" alt="">
1298        <span class="foot-name">Memorin — CS2 demo viewer</span>
1299      </div>
1300      <nav class="foot-links" aria-label="Footer">
1301        <a href="/legal.html">Legal</a>
1302        <a href="/privacy.html">Privacy</a>
1303        <a href="/support.html">Contact</a>
1304        <a href="/lab/sponsors/" data-nav="nav-sponsors" data-i18n="sponsors">Sponsors</a>
1305      </nav>
1306      
1307      <p class="foot-legal">Not affiliated with or endorsed by Valve. Counter-Strike 2 is a trademark of Valve Corporation.</p>
1308    </footer>
1309  </div>
1310</div>
1311
1312<div id="pro-modal" class="hidden" role="dialog" aria-modal="true" aria-labelledby="pro-title">
1313  <div class="pro-card" role="document">
1314    <button id="pro-close" type="button" class="account-close pro-close" aria-label="Close and go back">×</button>
1315    <div class="pro-main">
1316      <div class="pro-pitch">
1317        <p class="pro-eyebrow"><span class="pro-badge">PRO</span><span id="pro-reason"></span></p>
1318        <h2 id="pro-title">Upgrade to PRO</h2>
1319        <p id="pro-copy"></p>
1320      </div>
1321      
1322      <aside class="pro-buy">
1323        <div class="pro-buy-card">
1324          <div id="pro-plans" class="pro-plans"></div>
1325          <div id="pro-price">€9,99 / month or €69,99 / year</div>
1326          <button id="pro-upgrade" class="pro-upgrade" type="button">Upgrade to PRO</button>
1327          <button id="pro-refresh" class="pro-refresh" type="button">I subscribed — refresh status</button>
1328          <div id="pro-config-note" class="pro-config-note"></div>
1329        </div>
1330      </aside>
1331      <ul id="pro-features" class="pro-features"></ul>
1332    </div>
1333    <p class="pro-fine">Recurring subscription — cancel any time from the billing portal.
1334      <a href="/legal.html">Attribution &amp; takedown</a> · <a href="/privacy.html">Privacy &amp; retention</a></p>
1335  </div>
1336</div>
1337
1338<script nonce="t92TkfDfjA/i25i0rq4miQ==" type="module" src="/js/app.bundle.js?v=ecac764d24"></script>
vendor: 1 bytes, line 1338
1338
1339<script nonce="t92TkfDfjA/i25i0rq4miQ==" type="module" src="/js/molo_calibrate.js"></script>
vendor: 1 bytes, line 1339
1339
1340<script nonce="t92TkfDfjA/i25i0rq4miQ==" type="module" src="/js/envcal.js"></script>
vendor: 1 bytes, line 1340
1340
1341<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" nonce="t92TkfDfjA/i25i0rq4miQ==" data-cf-beacon='{"version":"2024.11.0","token":"7d810a24810d4656ab2834b8626d5656","r":1,"spa":2}' crossorigin="anonymous"></script>
1341
1342</body>
1343</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.