1<!DOCTYPE html> 2<html lang="en" class="scroll-smooth"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <!-- Screwcap tracking â injected by ops/legal-kit/inject-head.py. 7 The AdSense meta tag verifies ownership without loading the ad 8 network. The script itself stays behind the gate in js/ads.js. --> 9 <meta name="google-adsense-account" content="ca-pub-2067975098656294"> 10 <!-- Screwcap tracking â injected by ops/legal-kit/inject-head.py. 11 Plausible is ungated (cookieless); GA4 and the Meta Pixel sit behind 12 a Do-Not-Track gate inside screwcap-tracking.js and are never 13 requested at all when the browser has declined. --> 14
14<script src="/screwcap-tracking.js" defer></script>
14 15 <title>THE CHAIR â Federal Reserve Simulator</title> 16 <!-- Privacy-friendly analytics by Plausible (portfolio property: screwcap.games) --> 17
17<script async src="https://plausible.io/js/pa-d6bTHaTtSN8d3dQaPmfFZ.js"></script>
17 18
18<script> 19 window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)},plausible.init=plausible.init||function(i){plausible.o=i||{}}; 20 plausible.init() 21 </script>
21 22 <!-- Deck kill-switch / feature flags (fail-open; loads early so a kill applies fast) --> 23
23<script>window.SCREWCAP_TITLE='thechair';</script>
23 24
24<script src="/screwcap-flags.js"></script>
24 25 <!-- Deck telemetry â PII-free portfolio admin beacon (never blocks the game) --> 26
26<script src="/deck-beacon.js" defer></script>
26 27
27<script>document.addEventListener('DOMContentLoaded',function(){try{window.__deck=window.DeckBeacon&&DeckBeacon.init({title:'thechair-v2',collect:'/api/deck-collect'});}catch(e){}});</script>
27 28
28<script>window.SCREWCAP_GUARD={canonical:'https://chairmanmode.app',allow:['chairmanmode.app'],mode:'monitor'};</script>
28 29
29<script src="/screwcap-guard.js" defer></script>
29 30 <meta name="description" content="Step into the Federal Reserve. Set interest rates. Navigate crises. Try not to crash the economy. Free browser game grounded in real macroeconomics."> 31 <meta name="keywords" content="federal reserve simulator, economics game, monetary policy game, interest rate game, Fed Chair, macroeconomics, Taylor Rule, Phillips Curve"> 32 <meta name="author" content="ScrewCap, LLC"> 33 <meta name="robots" content="index, follow"> 34 35 <!-- PWA --> 36 <link rel="manifest" href="/manifest.json"> 37 <meta name="theme-color" content="#c49020"> 38 <meta name="mobile-web-app-capable" content="yes"> 39 <meta name="apple-mobile-web-app-capable" content="yes"> 40 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> 41 <meta name="apple-mobile-web-app-title" content="THE CHAIR"> 42 <link rel="apple-touch-icon" href="images/icon-192.png"> 43 <link rel="icon" type="image/png" sizes="32x32" href="images/icon-32.png"> 44 <link rel="icon" type="image/png" sizes="16x16" href="images/icon-16.png"> 45 <link rel="canonical" href="https://chairmanmode.app/"> 46 47 <!-- Open Graph --> 48 <meta property="og:type" content="website"> 49 <meta property="og:url" content="https://chairmanmode.app/"> 50 <meta property="og:title" content="THE CHAIR â Federal Reserve Simulator"> 51 <meta property="og:description" content="You have the most powerful unelected position in the world. 330 million Americans feel every decision. Can you stick the soft landing?"> 52 <meta property="og:image" content="https://chairmanmode.app/images/social-share.png"> 53 <meta property="og:site_name" content="THE CHAIR"> 54 <meta name="twitter:card" content="summary_large_image"> 55 <meta name="twitter:title" content="THE CHAIR â Federal Reserve Simulator"> 56 <meta name="twitter:description" content="Set interest rates. Navigate 1929, 2008, and the Volcker Shock. Try not to crash the economy. Free. Grounded in real macroeconomics."> 57 <meta name="twitter:image" content="https://chairmanmode.app/images/social-share.png"> 58 59 <!-- Fonts --> 60 <link rel="preconnect" href="https://fonts.googleapis.com"> 61 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 62 <link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Cinzel:wght@400;600;700&family=Cormorant+Garamond:ital,wght@0,400;0,600;0,700;1,400;1,600&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet"> 63 64 <!-- GSAP --> 65
65<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js" defer></script>
65 66
66<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js" defer></script>
66 67 68 <style> 69 /* ââ RESET ââ */ 70 *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } 71 72 :root { 73 /* Dark & Stormy Steampunk DC â June 2026 */ 74 --brass: #D4A017; /* Brass Glow â primary accent */ 75 --brass-lt: #F0C840; 76 --brass-dim: #8C6010; 77 --brass-glow: rgba(212,160,23,0.4); 78 --verdigris: #00BFA5; /* Storm Teal Lightning */ 79 --verd-glow: rgba(0,191,165,0.3); 80 --crimson: #9F2A2A; /* Crimson Ambition â danger */ 81 --violet: #5E2A7E; /* Thunder Purple â rare events */ 82 --bg: #0C0C0E; /* Void Storm Black */ 83 --surface: #1F1A17; /* Charcoal Leather */ 84 --surface2: #2C1F18; /* Deep Mahogany */ 85 --ink: #EDE4D5; /* Aged Ivory */ 86 --ink-dim: #8C8275; /* Fog Gray */ 87 --ink-faint: rgba(237,228,213,0.12); 88 --serif: 'Cinzel', 'Cormorant Garamond', Georgia, serif; 89 --display: 'Bebas Neue', 'Impact', sans-serif; 90 --mono: 'DM Mono', 'Courier New', monospace; 91 } 92 93 html { scroll-behavior: smooth; font-size: 16px; } 94 95 body { 96 background: var(--bg); 97 color: var(--ink); 98 font-family: var(--serif); 99 font-size: 1.05rem; 100 line-height: 1.6; 101 overflow-x: hidden; 102 -webkit-font-smoothing: antialiased; 103 } 104 105 a { text-decoration: none; color: inherit; } 106 ::selection { background: var(--brass); color: var(--bg); } 107 :focus-visible { outline: 2px solid var(--brass); outline-offset: 3px; } 108 109 /* ââ SCROLLBAR ââ */ 110 ::-webkit-scrollbar { width: 4px; } 111 ::-webkit-scrollbar-track { background: var(--bg); } 112 ::-webkit-scrollbar-thumb { background: var(--brass-dim); border-radius: 2px; } 113 114 /* ââ FILM GRAIN ââ */ 115 #grain { 116 position: fixed; inset: 0; 117 pointer-events: none; z-index: 9999; 118 opacity: 0.028; mix-blend-mode: overlay; 119 } 120 121 /* ââ GEAR BACKGROUND ââ */ 122 #gear-bg { 123 position: fixed; inset: 0; 124 pointer-events: none; z-index: 0; 125 overflow: hidden; 126 } 127 .gear-svg { position: absolute; fill: none; stroke: var(--brass); } 128 .gear-1 { width: 520px; height: 520px; top: -120px; right: -160px; stroke-width: 1.5; opacity: 0.035; animation: gear-cw 55s linear infinite; transform-origin: center; } 129 .gear-2 { width: 340px; height: 340px; bottom: 5%; left: -80px; stroke-width: 1.2; opacity: 0.028; animation: gear-ccw 40s linear infinite; transform-origin: center; } 130 .gear-3 { width: 220px; height: 220px; top: 38%; left: 50%; margin-left: -110px; stroke-width: 1; opacity: 0.022; animation: gear-cw 30s linear infinite; transform-origin: center; } 131 132 @keyframes gear-cw { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } 133 @keyframes gear-ccw { from { transform: rotate(0deg); } to { transform: rotate(-360deg); } } 134 135 /* ââ Storm rain overlay âââââââââââââââââââââââââââââââââââââââ */ 136 @keyframes rain-fall { 137 0% { transform: translateY(-100vh) translateX(0); opacity: 0.6; } 138 100% { transform: translateY(110vh) translateX(-20px); opacity: 0; } 139 } 140 @keyframes lightning-flash { 141 0%,92%,100% { opacity: 0; } 142 93% { opacity: 0.04; } 143 94% { opacity: 0; } 144 96% { opacity: 0.06; } 145 97% { opacity: 0; } 146 } 147 148 .rain-overlay { 149 position: fixed; inset: 0; z-index: 0; pointer-events: none; 150 overflow: hidden; 151 } 152 .rain-drop { 153 position: absolute; 154 width: 1.5px; top: -100px; 155 background: linear-gradient(to bottom, transparent, rgba(237,228,213,0.25), rgba(212,160,23,0.15), transparent); 156 animation: rain-fall linear infinite; 157 filter: blur(0.5px); 158 } 159 .storm-lightning { 160 position: fixed; inset: 0; z-index: 0; pointer-events: none; 161 background: rgba(0,191,165,0.08); 162 animation: lightning-flash 8s ease-in-out infinite; 163 }
164 @keyframes crimson-pulse { 165 0%,100%{box-shadow:0 0 0 0 rgba(159,42,42,0)} 166 50%{box-shadow:0 0 20px 4px rgba(159,42,42,0.3)} 167 } 168 169 /* ââ POWER-ON ââ */ 170 @keyframes power-on { 171 0% { opacity: 0; } 172 5% { opacity: 0.8; } 173 7% { opacity: 0.15; } 174 10% { opacity: 1; } 175 100% { opacity: 1; } 176 } 177 body { animation: power-on 1.6s ease-out forwards; } 178 179 /* ââ BACKGROUND CANVAS ââ */ 180 #bg-canvas { 181 position: fixed; inset: 0; 182 pointer-events: none; z-index: 0; 183 } 184 185 /* ââ RADIAL ATMOSPHERE ââ */ 186 .atm-glow { 187 position: fixed; pointer-events: none; z-index: 0; border-radius: 50%; 188 background: radial-gradient(ellipse at center, var(--brass-glow), transparent 65%); 189 } 190 .atm-1 { width: 700px; height: 400px; top: -10%; left: 30%; opacity: 0.22; } 191 .atm-2 { width: 500px; height: 300px; bottom: 10%; right: 10%; background: radial-gradient(ellipse at center, var(--verd-glow), transparent 65%); opacity: 0.16; } 192 193 /* ââ NAV ââ */ 194 #navbar { 195 position: fixed; top: 1.75rem; left: 0; right: 0; z-index: 1000; 196 padding: 1.1rem 2rem; 197 transition: background 0.4s, border-color 0.4s, backdrop-filter 0.4s; 198 border-bottom: 1px solid transparent; 199 } 200 #navbar.scrolled { 201 background: rgba(13,10,6,0.94); 202 border-color: rgba(196,144,32,0.2); 203 backdrop-filter: blur(18px); 204 } 205 .nav-inner { 206 max-width: 80rem; margin: 0 auto; 207 display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; 208 } 209 .nav-brand { 210 font-family: var(--display); 211 font-size: 1.5rem; letter-spacing: 0.18em; 212 color: var(--brass-lt); 213 text-shadow: 0 0 22px var(--brass-glow); 214 display: flex; align-items: center; gap: 0.5rem; 215 } 216 .nav-live { 217 display: flex; align-items: center; gap: 0.5rem; 218 font-family: var(--mono); font-size: 0.62rem; 219 letter-spacing: 0.14em; color: var(--ink-dim); 220 } 221 .live-dot { 222 width: 7px; height: 7px; border-radius: 50%; 223 background: var(--verdigris); flex-shrink: 0; 224 animation: verd-pulse 2s ease-in-out infinite; 225 } 226 @keyframes verd-pulse { 227 0%,100% { box-shadow: 0 0 0 0 rgba(74,154,143,0.7); } 228 60% { box-shadow: 0 0 0 8px rgba(74,154,143,0); } 229 } 230 .nav-cta { 231 font-family: var(--mono); font-size: 0.7rem; 232 letter-spacing: 0.16em; text-transform: uppercase; 233 background: var(--brass); color: var(--bg); 234 padding: 0.5rem 1.25rem; 235 border: none; cursor: pointer; 236 font-weight: 500; 237 transition: background 0.2s, transform 0.18s, box-shadow 0.2s; 238 display: inline-block; 239 } 240 .nav-cta:hover { 241 background: var(--brass-lt); 242 transform: translateY(-2px); 243 box-shadow: 0 6px 24px var(--brass-glow); 244 } 245 246 /* ââ BUTTONS ââ */ 247 .btn-primary { 248 font-family: var(--display); 249 font-size: clamp(0.9rem,1.5vw,1.1rem); 250 letter-spacing: 0.14em; 251 background: var(--brass); 252 color: var(--bg); 253 border: none; cursor: pointer; 254 padding: 1rem 2.4rem; 255 position: relative; overflow: hidden; 256 transition: background 0.2s, transform 0.18s, box-shadow 0.22s; 257 display: inline-block; 258 } 259 .btn-primary::before { 260 content: ''; 261 position: absolute; top: 0; left: -100%; 262 width: 60%; height: 100%; 263 background: linear-gradient(90deg, transparent, rgba(255,255,255,0.22), transparent); 264 transition: left 0.45s ease; 265 } 266 .btn-primary:hover { background: var(--brass-lt); transform: translateY(-3px); box-shadow: 0 10px 36px var(--brass-glow); } 267 .btn-primary:hover::before { left: 160%; } 268 .btn-secondary { 269 font-family: var(--mono); font-size: 0.78rem; 270 letter-spacing: 0.15em; text-transform: uppercase; 271 background: transparent; color: var(--ink-dim); 272 border: 1px solid var(--brass-dim); 273 padding: 0.85rem 1.75rem; cursor: pointer; 274 transition: color 0.2s, border-color 0.2s, background 0.2s, transform 0.18s; 275 display: inline-block; 276 } 277 .btn-secondary:hover { 278 color: var(--ink); border-color: var(--brass); 279 background: rgba(196,144,32,0.08); 280 transform: translateY(-2px); 281 } 282 283 /* ââ SECTION SHARED ââ */ 284 section { position: relative; z-index: 1; } 285 .container { max-width: 74rem; margin: 0 auto; padding: 0 1.5rem; } 286 .section-label { 287 font-family: var(--mono); font-size: 0.6rem; 288 letter-spacing: 0.28em; text-transform: uppercase; 289 color: var(--brass); margin-bottom: 0.75rem; 290 } 291 .section-title { 292 font-family: var(--display); 293 font-size: clamp(2.4rem,5vw,4rem); 294 letter-spacing: 0.06em; line-height: 1.05; 295 color: var(--ink); 296 } 297 .divider { 298 height: 1px; 299 background: linear-gradient(90deg, transparent, rgba(196,144,32,0.3), transparent); 300 } 301 302 /* ââ REVEAL ââ */ 303 .reveal { opacity: 0; transform: translateY(24px); transition: opacity 0.7s ease, transform 0.7s ease; } 304 .reveal.in { opacity: 1; transform: none; } 305 .d1 { transition-delay: 0.08s; } 306 .d2 { transition-delay: 0.18s; } 307 .d3 { transition-delay: 0.28s; } 308 .d4 { transition-delay: 0.38s; } 309 310 /* ââ TOP MARKET TICKER ââ */ 311 #top-ticker { 312 position: fixed; top: 0; left: 0; right: 0; z-index: 900; 313 background: rgba(13,10,6,0.97); 314 border-bottom: 1px solid rgba(196,144,32,0.22); 315 backdrop-filter: blur(12px); 316 overflow: hidden; height: 1.75rem; 317 display: flex; align-items: center; 318 /* A scrolling marquee always shows a mid-character item right at the box edge â 319 that's inherent to the animation, not fixable by resizing. Fading the edges 320 (Bloomberg-terminal convention) makes the cutoff read as intentional instead 321 of clipped/broken, which is what the "US10Y 5." cut-off report was catching. */ 322 mask-image: linear-gradient(to right, transparent, #000 1.5rem, #000 calc(100% - 1.5rem), transparent); 323 -webkit-mask-image: linear-gradient(to right, transparent, #000 1.5rem, #000 calc(100% - 1.5rem), transparent); 324 } 325 #top-ticker .top-ticker-scroll { 326 display: inline-flex; align-items: center; gap: 0; 327 animation: ticker 55s linear infinite; white-space: nowrap; 328 font-family: var(--mono); font-size: 0.62rem; 329 } 330 #top-ticker .top-ticker-scroll:hover { animation-play-state: paused; } 331 .tt-item { display: inline-flex; align-items: center; gap: 0.45rem; padding: 0 1rem; } 332 .tt-sym { color: var(--brass); font-weight: 600; letter-spacing: 0.08em; } 333 .tt-val { color: var(--ink); } 334 335 #fed-news-ticker { border-top: 1px solid var(--ink-faint); } 336 .fn-age { color: var(--verdigris); font-family: var(--mono); font-size: 0.7rem; margin-right: 0.5rem; } 337 .fn-text { color: var(--ink-dim); } 338 339 #spicy-toggle { 340 background: transparent; border: 1px solid var(--brass-dim); color: var(--brass); 341 font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.06em; 342 padding: 0.35rem 0.8rem; border-radius: 3px; cursor: pointer; transition: all .2s; 343 } 344 #spicy-toggle:hover { border-color: var(--brass); background: rgba(212,160,23,0.08); } 345 #board-odds-panel { 346 max-width: 560px; margin: 0.75rem auto 0; padding: 0.9rem 1.1rem; 347 border: 1px solid var(--ink-faint); border-radius: 4px; text-align: left; 348 font-family: var(--mono); font-size: 0.72rem; 349 } 350 #board-odds-panel h4 { 351 margin: 0 0 0.5rem; color: var(--brass); font-family: var(--serif); 352 font-size: 0.85rem; letter-spacing: 0.04em; text-align: center; 353 } 354 .bo-row { display: flex; justify-content: space-between; padding: 0.18rem 0; color: var(--ink); } 355 .bo-row .bo-bar-wrap { flex: 1; margin: 0 0.6rem; background: var(--ink-faint); height: 6px; border-radius: 3px; align-self: center; overflow: hidden; } 356 .bo-row .bo-bar { height: 100%; background: var(--verdigris); }
357 .bo-source { color: var(--ink-dim); font-size: 0.62rem; margin-top: 0.5rem; text-align: center; } 358 .bo-source a { color: var(--ink-dim); } 359 .tt-up { color: #4a9a8f; } 360 .tt-dn { color: #c0392b; } 361 .tt-sep { color: rgba(196,144,32,0.25); margin-left: 0.5rem; } 362 363 /* ââ HERO ââ */ 364 #hero { 365 min-height: 100svh; 366 display: flex; flex-direction: column; justify-content: center; align-items: center; 367 padding: 5.5rem 1.5rem 4rem; 368 position: relative; z-index: 1; 369 text-align: center; 370 background-image: url('images/hero-chair.jpg'); 371 background-size: cover; 372 background-position: center 30%; 373 } 374 /* Video background */ 375 #hero-video-bg { 376 position: absolute; inset: 0; z-index: 0; 377 width: 100%; height: 100%; object-fit: cover; object-position: center 30%; 378 opacity: 0; transition: opacity 2s ease; 379 } 380 #hero-video-bg.loaded { opacity: 0.85; } 381 /* Dark vignette so text stays readable */ 382 #hero::before { 383 content: ''; position: absolute; inset: 0; z-index: 1; 384 background: 385 linear-gradient(to bottom, rgba(12,12,14,0.55) 0%, rgba(12,12,14,0.3) 40%, rgba(12,12,14,0.75) 100%), 386 radial-gradient(ellipse at center, transparent 30%, rgba(12,12,14,0.5) 80%); 387 pointer-events: none; 388 } 389 #hero .container { position: relative; z-index: 2; } 390 #hero .container { position: relative; z-index: 1; } 391 #hero .container { display: flex; flex-direction: column; align-items: center; } 392 .hero-eyebrow { 393 font-family: var(--mono); font-size: 0.75rem; 394 letter-spacing: 0.32em; text-transform: uppercase; 395 color: var(--ink-dim); margin-bottom: 1.5rem; 396 } 397 .hero-title { 398 font-family: var(--display); 399 font-size: clamp(5rem,14vw,11rem); 400 letter-spacing: 0.04em; line-height: 0.88; 401 margin-bottom: 1.25rem; 402 } 403 .hero-title .the { color: var(--ink-dim); } 404 .hero-title .chair { 405 color: var(--brass-lt); 406 text-shadow: 0 0 60px rgba(232,184,64,0.4), 0 0 120px rgba(196,144,32,0.2); 407 } 408 .hero-sub { 409 font-family: var(--serif); font-size: clamp(1rem,2vw,1.2rem); 410 font-weight: 600; color: rgba(245,234,216,0.75); 411 max-width: 34rem; line-height: 1.55; margin-bottom: 2rem; 412 } 413 .hero-sub em { color: var(--ink); font-style: normal; } 414 415 /* ââ LIVE STATS ROW ââ */ 416 .stats-row { 417 display: flex; flex-wrap: wrap; gap: 1px; 418 background: var(--brass-dim); border: 1px solid var(--brass-dim); 419 margin-bottom: 3.5rem; max-width: 42rem; 420 } 421 .stat-cell { 422 background: var(--surface); padding: 1rem 1.5rem; flex: 1; min-width: 120px; 423 text-align: center; 424 } 425 .stat-val { 426 font-family: var(--display); font-size: clamp(1.8rem,3vw,2.4rem); 427 letter-spacing: 0.04em; line-height: 1; color: var(--brass-lt); 428 } 429 .stat-val.green { color: var(--verdigris); } 430 .stat-val.white { color: rgba(245,234,216,0.65); } 431 .stat-key { 432 font-family: var(--mono); font-size: 0.55rem; 433 letter-spacing: 0.22em; text-transform: uppercase; 434 color: var(--ink-dim); margin-top: 0.3rem; 435 } 436 437 /* ââ MISSION BAR (bottom ticker) ââ */ 438 #mission-bar { 439 position: fixed; bottom: 0; left: 0; right: 0; z-index: 800; 440 background: rgba(13,10,6,0.97); 441 border-top: 1px solid rgba(196,144,32,0.22); 442 backdrop-filter: blur(12px); 443 padding: 0.4rem 1.5rem; 444 } 445 .mc-inner { 446 max-width: 80rem; margin: 0 auto; 447 display: flex; align-items: center; gap: 1.5rem; 448 } 449 .mc-live { 450 font-family: var(--mono); font-size: 0.6rem; 451 letter-spacing: 0.2em; color: var(--verdigris); 452 flex-shrink: 0; display: flex; align-items: center; gap: 0.4rem; 453 } 454 .mc-indicators { 455 display: flex; gap: 1.5rem; flex-shrink: 0; 456 } 457 .mc-ind { 458 display: flex; align-items: center; gap: 0.35rem; 459 } 460 .mc-label { font-family: var(--mono); font-size: 0.55rem; letter-spacing: 0.1em; color: var(--ink-dim); } 461 .mc-val { font-family: var(--mono); font-size: 0.68rem; font-weight: 500; } 462 .ticker-wrap { 463 overflow: hidden; white-space: nowrap; flex: 1; min-width: 0; 464 mask-image: linear-gradient(to right, transparent, #000 1rem, #000 calc(100% - 1rem), transparent); 465 -webkit-mask-image: linear-gradient(to right, transparent, #000 1rem, #000 calc(100% - 1rem), transparent); 466 } 467 .ticker-inner { display: inline-block; animation: ticker 38s linear infinite; font-family: var(--mono); font-size: 0.58rem; color: rgba(245,234,216,0.65); letter-spacing: 0.06em; }
468 @keyframes ticker { from { transform: translateX(0); } to { transform: translateX(-50%); } } 469 470 /* ââ MEDIA FEED ââ */ 471 .media-grid { display: grid; grid-template-columns: repeat(auto-fit,minmax(280px,1fr)); gap: 1rem; } 472 .media-card { 473 background: var(--surface); border: 1px solid rgba(196,144,32,0.12); 474 padding: 1.5rem; position: relative; overflow: hidden; 475 transition: border-color 0.3s; 476 } 477 .media-card:hover { border-color: rgba(196,144,32,0.35); } 478 .media-card::before { 479 content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px; 480 background: linear-gradient(90deg, transparent, var(--brass), transparent); 481 opacity: 0; transition: opacity 0.3s; 482 } 483 .media-card:hover::before { opacity: 1; } 484 485 /* ââ WAR ROOM BRIEFING CARDS ââ */ 486 .war-room-grid { 487 display: grid; grid-template-columns: repeat(auto-fit,minmax(250px,1fr)); gap: 1px; 488 background: var(--brass-dim); border: 1px solid var(--brass-dim); 489 } 490 .wr-card { 491 background: var(--surface); padding: 2rem 1.75rem; 492 position: relative; overflow: hidden; cursor: default; 493 transition: background 0.3s; 494 } 495 .wr-card:hover { background: var(--surface2); } 496 .wr-card::after { 497 content: ''; 498 position: absolute; top: 0; left: 0; bottom: 0; width: 2px; 499 background: var(--brass); opacity: 0; 500 transition: opacity 0.3s; 501 } 502 .wr-card:hover::after { opacity: 1; } 503 .wr-label { 504 font-family: var(--mono); font-size: 0.58rem; 505 letter-spacing: 0.22em; text-transform: uppercase; 506 color: var(--brass); margin-bottom: 0.6rem; 507 } 508 .wr-title { 509 font-family: var(--display); font-size: 1.55rem; 510 letter-spacing: 0.06em; color: var(--ink); line-height: 1.1; 511 margin-bottom: 1rem; 512 } 513 .wr-visual { margin-bottom: 1rem; } 514 .wr-body { 515 font-family: var(--serif); font-size: 0.9rem; color: var(--ink-dim); line-height: 1.65; 516 } 517 .wr-reveal { 518 max-height: 0; overflow: hidden; opacity: 0; 519 transition: max-height 0.4s ease, opacity 0.4s ease; 520 } 521 .wr-card:hover .wr-reveal { max-height: 120px; opacity: 1; } 522 .wr-tooltip { 523 margin-top: 0.75rem; padding: 0.6rem 0.85rem; 524 background: rgba(196,144,32,0.07); border-left: 2px solid var(--brass); 525 font-family: var(--mono); font-size: 0.65rem; 526 letter-spacing: 0.04em; color: var(--brass); 527 font-style: italic; 528 } 529 530 /* ââ SCENARIO CARDS ââ */ 531 .sc-grid { display: grid; grid-template-columns: repeat(auto-fit,minmax(240px,1fr)); gap: 1rem; } 532 .sc-card { 533 background: var(--surface); border: 1px solid rgba(196,144,32,0.1); 534 padding: 2rem 1.75rem; position: relative; overflow: hidden; cursor: pointer; 535 transition: transform 0.28s cubic-bezier(0.25,0.46,0.45,0.94), border-color 0.28s, box-shadow 0.28s; 536 } 537 .sc-card::before { 538 content: ''; position: absolute; inset: 0; 539 background: radial-gradient(ellipse at 50% 0%, rgba(196,144,32,0.1), transparent 60%); 540 opacity: 0; transition: opacity 0.3s; 541 } 542 .sc-card:hover { transform: translateY(-6px); border-color: rgba(196,144,32,0.45); box-shadow: 0 20px 50px rgba(196,144,32,0.12); } 543 .sc-card:hover::before { opacity: 1; } 544 .sc-card.featured { border-color: rgba(196,144,32,0.25); } 545 .sc-card.sponsored { border-color: rgba(74,154,143,0.25); } 546 .sc-card.sponsored:hover { border-color: var(--verdigris); box-shadow: 0 20px 50px rgba(74,154,143,0.12); } 547 .sc-era { 548 font-family: var(--mono); font-size: 0.82rem; font-weight: 500; 549 color: var(--brass); letter-spacing: 0.06em; 550 } 551 .sc-era.dim { color: var(--ink-dim); } 552 .sc-era.verd { color: var(--verdigris); } 553 .sc-name { font-family: var(--display); font-size: 1.6rem; letter-spacing: 0.04em; color: var(--ink); margin: 0.5rem 0; } 554 .sc-desc { font-family: var(--serif); font-size: 0.85rem; color: var(--ink-dim); line-height: 1.65; margin-bottom: 1.5rem; } 555 .sc-survival { font-family: var(--display); font-size: 2.2rem; letter-spacing: 0.04em; color: var(--brass-lt); line-height: 1; } 556 .sc-survival.danger { color: var(--crimson); animation: crimson-pulse 2.5s ease-in-out infinite; } 557 .sc-survlabel { font-family: var(--mono); font-size: 0.52rem; letter-spacing: 0.22em; text-transform: uppercase; color: var(--ink-dim); margin-top: 0.15rem; margin-bottom: 1.25rem; } 558 559 .badge { 560 font-family: var(--mono); font-size: 0.55rem; font-weight: 500; 561 letter-spacing: 0.14em; text-transform: uppercase; 562 padding: 0.2rem 0.55rem; border: 1px solid; 563 } 564 .badge-rookie { color: #4ade80; border-color: rgba(74,222,128,0.3); background: rgba(74,222,128,0.07); } 565 .badge-analyst { color: var(--brass-lt); border-color: rgba(232,184,64,0.3); background: rgba(232,184,64,0.07); } 566 .badge-chair { color: #fb923c; border-color: rgba(251,146,60,0.3); background: rgba(251,146,60,0.07); } 567 .badge-legend { color: #f87171; border-color: rgba(248,113,113,0.3); background: rgba(248,113,113,0.07); } 568 .badge-sponsored { color: var(--verdigris); border-color: rgba(74,154,143,0.35); background: rgba(74,154,143,0.07); } 569 570 /* ââ TESTIMONIALS ââ */ 571 .testimonial { 572 background: var(--surface); 573 border: 1px solid rgba(196,144,32,0.1); 574 border-left: 2px solid var(--brass); 575 padding: 1.5rem 2rem; 576 } 577 578 /* ââ SPONSORSHIP ROW ââ */ 579 .sponsor-row { 580 display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; justify-content: center; 581 padding: 1.25rem 0; 582 border-top: 1px solid rgba(196,144,32,0.1); 583 border-bottom: 1px solid rgba(196,144,32,0.1); 584 } 585 .sponsor-slot { 586 font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.12em; 587 color: var(--ink-dim); border: 1px solid rgba(196,144,32,0.15); 588 padding: 0.35rem 0.85rem; 589 transition: border-color 0.2s, color 0.2s; cursor: pointer; 590 } 591 .sponsor-slot:hover { border-color: var(--brass-dim); color: var(--brass); } 592 .sponsor-label { font-family: var(--mono); font-size: 0.52rem; letter-spacing: 0.2em; color: var(--ink-dim);
592 opacity: 0.5; } 593 594 /* ââ FOOTER ââ */ 595 footer { 596 border-top: 1px solid rgba(196,144,32,0.12); 597 padding: 2.5rem 1.5rem; position: relative; z-index: 1; 598 } 599 .footer-inner { 600 max-width: 74rem; margin: 0 auto; 601 display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1.5rem; 602 } 603 .footer-brand { font-family: var(--display); font-size: 1.2rem; letter-spacing: 0.2em; color: var(--brass-dim); } 604 .footer-links { display: flex; flex-wrap: wrap; gap: 1.5rem; } 605 .footer-links a { font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); transition: color 0.2s; } 606 .footer-links a:hover { color: var(--brass); } 607 608 /* The nav line is longer than the headcount it replaced ("DUAL MANDATE: PRICE 609 STABILITY & MAXIMUM EMPLOYMENT", or the live 10Y). Between 640 and 1024 it wrapped 610 to two lines and collided with the hero eyebrow, so it now stands down earlier. */ 611 /* !important because the element carries an inline display:flex â which is also why 612 the 640px rule below had never actually hidden it on a phone. */ 613 #nav-ust { white-space: nowrap; } 614 @media (max-width: 1024px) { 615 .nav-live-wrap { display: none !important; } 616 } 617 618 /* ââ MOBILE ââ */ 619 @media (max-width: 640px) { 620 #mission-bar { display: none; } 621 .nav-live-wrap { display: none !important; } 622 /* Brand + CTA no longer fit one line at this width once nav-live-wrap is 623 hidden and .nav-brand still wraps ("THE" / "CHAIR") â a taller, wrapped 624 fixed navbar then overlapped the hero eyebrow text underneath it. Shrink 625 both so the row stays one line, and give the hero extra top padding as a 626 safety margin regardless. */ 627 .nav-brand { font-size: 1.1rem; letter-spacing: 0.12em; white-space: nowrap; } 628 .nav-cta { font-size: 0.6rem; padding: 0.45rem 0.9rem; white-space: nowrap; } 629 #hero { padding-top: 7.5rem; } 630 } 631 </style>
632<script defer src="/_vercel/insights/script.js"></script>
632 633</head> 634<body> 635<noscript> 636 <div style="max-width:760px;margin:0 auto;padding:2rem;font-family:system-ui,sans-serif;color:#e8e8e8;background:#0c0c0e;line-height:1.6"> 637 <h1>The Chair â Federal Reserve Simulator</h1> 638 <p>Take the Fed Chair's seat: set interest rates, manage the dual mandate, and survive history's hardest economic crises. <strong>JavaScript is required to play.</strong></p> 639 <h2>More from Screwcap Games</h2> 640 <ul> 641 <li><a href="https://sisterwendy.com">Sister Wendy â All-Fives Dominoes</a></li> 642 <li><a href="https://gold-digger-two.vercel.app">Gold Digger â Commodities Prediction Markets</a></li> 643 <li><a href="https://www.sutda.games">Sutda â Korean Card Bluffing</a></li> 644 <li><a href="https://dttau.app">DTTAU â Do Things That Add Up</a></li> 645 <li><a href="https://screwcap.games">All Screwcap Games</a></li> 646 </ul> 647 </div> 648</noscript> 649<!-- Storm atmosphere --> 650<div class="rain-overlay" id="rain-overlay" aria-hidden="true"></div> 651<div class="storm-lightning" aria-hidden="true"></div>
652<script> 653// Generate rain drops 654(function(){ 655 const overlay = document.getElementById('rain-overlay'); 656 if (!overlay) return; 657 for (let i = 0; i < 60; i++) { 658 const drop = document.createElement('div'); 659 drop.className = 'rain-drop'; 660 drop.style.left = Math.random() * 100 + 'vw'; 661 drop.style.height = (40 + Math.random() * 60) + 'px'; 662 drop.style.animationDuration = (1.5 + Math.random() * 2) + 's'; 663 drop.style.animationDelay = '-' + (Math.random() * 3) + 's'; 664 drop.style.opacity = (0.1 + Math.random() * 0.3).toString(); 665 overlay.appendChild(drop); 666 } 667})(); 668</script>
668 669 670 <!-- TOP MARKET TICKER â Bloomberg-style macro strip --> 671 <!-- The live macro strip. 672 This was twelve hardcoded figures with hardcoded up/down arrows â US10Y 4.28%, 673 S&P 5,421, GOLD $3,247, VIX 18.4, CPI 3.2% â none of which had ever moved, and one 674 of which disagreed with the real 10-year the nav below it had started fetching. 675 It now renders from /api/markets (FRED) or it renders nothing. There is no fallback 676 row of plausible constants, because that is precisely what was wrong with it. --> 677 <div id="top-ticker" aria-label="Live macro data" hidden> 678 <div class="top-ticker-scroll" id="top-ticker-scroll"></div> 679 </div> 680 681 <!-- Real Fed news, delayed on purpose (see api/fed-news.js). Same "renders from real 682 data or stays hidden" rule as the strip above â no invented headlines. --> 683 <div id="fed-news-ticker" aria-label="Recent Fed news" hidden> 684 <div class="top-ticker-scroll" id="fed-news-scroll"></div> 685 </div> 686 687 <!-- FILM GRAIN --> 688 <div id="grain" aria-hidden="true"></div> 689 690 <!-- ATMOSPHERE GLOWS --> 691 <div class="atm-glow atm-1" aria-hidden="true"></div> 692 <div class="atm-glow atm-2" aria-hidden="true"></div> 693 694 <!-- GEAR BACKGROUND --> 695 <div id="gear-bg" aria-hidden="true"> 696 <!-- Large gear top-right --> 697 <svg class="gear-svg gear-1" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"> 698 <circle cx="100" cy="100" r="72" stroke-width="1.5"/> 699 <circle cx="100" cy="100" r="50" stroke-width="1"/> 700 <circle cx="100" cy="100" r="12" stroke-width="1.5"/> 701 <!-- teeth --> 702 <g stroke-width="1.5"> 703 <rect x="93" y="18" width="14" height="14" rx="1"/> 704 <rect x="93" y="168" width="14" height="14" rx="1"/> 705 <rect x="18" y="93" width="14" height="14" rx="1"/> 706 <rect x="168" y="93" width="14" height="14" rx="1"/> 707 <rect x="130" y="28" width="14" height="14" rx="1" transform="rotate(30 137 35)"/> 708 <rect x="56" y="28" width="14" height="14" rx="1" transform="rotate(-30 63 35)"/> 709 <rect x="130" y="158" width="14" height="14" rx="1" transform="rotate(-30 137 165)"/> 710 <rect x="56" y="158" width="14" height="14" rx="1" transform="rotate(30 63 165)"/> 711 <rect x="22" y="128" width="14" height="14" rx="1" transform="rotate(30 29 135)"/> 712 <rect x="22" y="58" width="14" height="14" rx="1" transform="rotate(-30 29 65)"/> 713 <rect x="164" y="128" width="14" height="14" rx="1" transform="rotate(-30 171 135)"/> 714 <rect x="164" y="58" width="14" height="14" rx="1" transform="rotate(30 171 65)"/> 715 </g> 716 </svg> 717 718 <!-- Medium gear bottom-left --> 719 <svg class="gear-svg gear-2" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"> 720 <circle cx="100" cy="100" r="72" stroke-width="1.2"/> 721 <circle cx="100" cy="100" r="48" stroke-width="0.9"/> 722 <circle cx="100" cy="100" r="12" stroke-width="1.2"/> 723 <g stroke-width="1.2"> 724 <rect x="93" y="18" width="14" height="14" rx="1"/> 725 <rect x="93" y="168" width="14" height="14" rx="1"/> 726 <rect x="18" y="93" width="14" height="14" rx="1"/> 727 <rect x="168" y="93" width="14" height="14" rx="1"/> 728 <rect x="130" y="28" width="14" height="14" rx="1" transform="rotate(30 137 35)"/> 729 <rect x="56" y="28" width="14" height="14" rx="1" transform="rotate(-30 63 35)"/> 730 <rect x="130" y="158" width="14" height="14" rx="1" transform="rotate(-30 137 165)"/> 731 <rect x="56" y="158" width="14" height="14" rx="1" transform="rotate(30 63 165)"/> 732 </g> 733 </svg> 734 735 <!-- Small gear center --> 736 <svg class="gear-svg gear-3" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"> 737 <circle cx="100" cy="100" r="72" stroke-width="1"/> 738 <circle cx="100" cy="100" r="46" stroke-width="0.8"/> 739 <circle cx="100" cy="100" r="12" stroke-width="1"/> 740 <g stroke-width="1"> 741 <rect x="93" y="18" width="14" height="14" rx="1"/> 742 <rect x="93" y="168" width="14" height="14" rx="1"/> 743 <rect x="18" y="93" width="14" height="14" rx="1"/> 744 <rect x="168" y="93" width="14" height="14" rx="1"/> 745 </g> 746 </svg> 747 </div> 748 749 <!-- ECONOMIC BACKGROUND CANVAS -->
750 <canvas id="bg-canvas" aria-hidden="true"></canvas> 751 752 <!-- ââ NAVBAR ââ --> 753 <nav id="navbar" aria-label="Main navigation"> 754 <div class="nav-inner"> 755 <a href="/" class="nav-brand" aria-label="THE CHAIR home"> 756 <svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.3" opacity="0.7" aria-hidden="true"> 757 <circle cx="10" cy="10" r="8"/> 758 <circle cx="10" cy="10" r="4"/> 759 <line x1="10" y1="2" x2="10" y2="18"/> 760 <line x1="2" y1="10" x2="18" y2="10"/> 761 </svg> 762 THE CHAIR 763 </a> 764 <div class="nav-live-wrap" style="display:flex;align-items:center;gap:1.5rem"> 765 <div class="nav-live"> 766 <div class="live-dot"></div> 767 <span id="nav-ust" data-fallback="DUAL MANDATE: PRICE STABILITY & MAXIMUM EMPLOYMENT">DUAL MANDATE: <span style="color:var(--verdigris)">PRICE STABILITY</span> & <span style="color:var(--verdigris)">MAXIMUM EMPLOYMENT</span></span> 768 </div> 769 </div> 770 <a href="game.html?scenario=modern" class="nav-cta" onmouseenter="playH(880)" onclick="playH(1100)"> 771 TAKE THE CHAIR â 772 </a> 773 </div> 774 </nav> 775 776 <!-- ââ HERO ââ --> 777 <section id="hero"> 778 <video id="hero-video-bg" autoplay muted loop playsinline preload="auto" 779 oncanplay="this.classList.add('loaded')"> 780 <source src="videos/hero-storm.mp4" type="video/mp4"> 781 </video> 782 <div class="container"> 783 <div class="hero-eyebrow reveal">BOARD OF GOVERNORS · FEDERAL RESERVE SYSTEM · WASHINGTON D.C.</div> 784 785 <h1 class="hero-title reveal d1"> 786 <div class="the">THE</div> 787 <div class="chair">CHAIR</div> 788 </h1> 789 790 <div class="hero-sub reveal d2"> 791 You're in The Chair. The storm is coming.<br> 792 <em>What will you do?</em> 793 </div> 794 795 <div style="font-size:0.9rem;color:var(--ink-dim);max-width:560px;margin:0 auto 1.5rem;font-style:italic;text-align:center"> 796 Not just a rate-setting game. You're managing four egos with PhDs, a press corps that wants blood, and a Senate that blames you for everything â including the weather. 797 </div> 798 799 <div class="reveal d3" style="display:flex;flex-wrap:wrap;gap:1rem;justify-content:center;margin-bottom:2rem"> 800 <a href="game.html?scenario=modern" class="btn-primary" onmouseenter="playH(660)" onclick="playH(880)"> 801 ENTER THE OVAL â 802 </a> 803 <a href="#scenarios" class="btn-secondary" onmouseenter="playH(440)"> 804 CHOOSE YOUR STORM â 805 </a> 806 </div> 807 808 <div class="reveal d4" style="font-family:var(--serif);font-size:0.9rem;color:var(--ink-dim);font-style:italic;max-width:32rem;line-height:1.65;margin-bottom:2.5rem"> 809 330 million Americans feel every decision you make. The board feels every decision you make differently. 810 </div> 811 812 <div class="stats-row reveal d4" style="max-width:38rem;width:100%"> 813 <div class="stat-cell"> 814 <div class="stat-val">2%</div> 815 <div class="stat-key">Inflation Target</div> 816 </div> 817 <div class="stat-cell"> 818 <div class="stat-val green">12</div> 819 <div class="stat-key">FOMC Members Voting</div> 820 </div> 821 <div class="stat-cell"> 822 <div class="stat-val white">8</div> 823 <div class="stat-key">Meetings Per Year</div> 824 </div> 825 </div> 826 </div> 827 828 <!-- scroll hint --> 829 <div style="position:absolute;bottom:2.5rem;left:50%;transform:translateX(-50%);text-align:center;display:none" class="scroll-hint"> 830 <div style="font-family:var(--mono);font-size:0.55rem;letter-spacing:0.3em;color:var(--ink-dim)">SCROLL</div> 831 <div style="margin-top:0.3rem;color:var(--brass-dim);animation:blink-y 1.6s ease-in-out infinite">â</div> 832 </div> 833 </section> 834 <style>.scroll-hint{display:block!important}@keyframes blink-y{0%,100%{opacity:0.6}50%{opacity:0.15}}</style> 835 836 <!-- ââ CAREER LADDER (fusion) ââ --> 837 <section id="ladder" style="position:relative;padding:5rem 1.5rem;background:linear-gradient(180deg,#0a0d12 0%,#0d1117 100%);border-top:1px solid rgba(0,191,165,0.12)"> 838 <div class="container" style="max-width:1080px;margin:0 auto;text-align:center"> 839 <div class="hero-eyebrow" style="letter-spacing:0.25em;font-size:0.62rem;color:var(--verdigris);margin-bottom:0.75rem">THE CAREER · FROM THE STAFF DESK TO THE CORNER OFFICE</div>
840 <h2 style="font-family:var(--serif,'Playfair Display',serif);font-size:clamp(1.8rem,4vw,2.8rem);font-weight:700;color:#f0c850;margin:0 0 0.75rem">Four Seats. One Economy.</h2> 841 <p style="font-size:0.95rem;color:var(--ink-dim);max-width:38rem;margin:0 auto 2.75rem;line-height:1.6;font-style:italic"> 842 Start at the training desk with the hints on. Earn your way to the live economy. The model deepens, the coaching goes quiet, and eventually it's just you and 330 million people. 843 </p> 844 <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:1rem;text-align:left"> 845 846 <a href="game.html?tier=pilot" style="display:block;padding:1.5rem;border:1px solid rgba(0,191,165,0.35);border-radius:14px;background:rgba(0,191,165,0.04);text-decoration:none;color:inherit;transition:transform .15s,border-color .15s" onmouseenter="this.style.transform='translateY(-4px)';this.style.borderColor='rgba(0,191,165,0.7)'" onmouseleave="this.style.transform='';this.style.borderColor='rgba(0,191,165,0.35)'"> 847 <div style="font-size:1.8rem;margin-bottom:0.5rem">ð</div> 848 <div style="font-family:var(--mono,monospace);font-size:0.6rem;letter-spacing:0.18em;color:var(--verdigris);margin-bottom:0.35rem">TIER 1 · THE TRAINING DESK</div> 849 <div style="font-size:1.15rem;font-weight:700;color:#f0c850;margin-bottom:0.4rem">STAFF ECONOMIST</div> 850 <div style="font-size:0.82rem;color:var(--ink-dim);line-height:1.5">The desk with training wheels: IS-LM lens, Taylor-rule hints, plain-English coaching.</div> 851 <div style="margin-top:0.9rem;font-family:var(--mono,monospace);font-size:0.68rem;color:var(--verdigris);font-weight:600">START HERE â</div> 852 </a> 853 854 <a href="game.html?tier=governor" style="display:block;padding:1.5rem;border:1px solid rgba(240,200,80,0.28);border-radius:14px;background:rgba(240,200,80,0.03);text-decoration:none;color:inherit;transition:transform .15s,border-color .15s" onmouseenter="this.style.transform='translateY(-4px)';this.style.borderColor='rgba(240,200,80,0.6)'" onmouseleave="this.style.transform='';this.style.borderColor='rgba(240,200,80,0.28)'"> 855 <div style="font-size:1.8rem;margin-bottom:0.5rem">ðï¸</div> 856 <div style="font-family:var(--mono,monospace);font-size:0.6rem;letter-spacing:0.18em;color:#f0c850;margin-bottom:0.35rem">TIER 2 · THE BRIDGE</div> 857 <div style="font-size:1.15rem;font-weight:700;color:#f0c850;margin-bottom:0.4rem">GOVERNOR</div> 858 <div style="font-size:0.82rem;color:var(--ink-dim);line-height:1.5">Board, dual mandate, credibility, expectations. The training wheels come off.</div> 859 <div style="margin-top:0.9rem;font-family:var(--mono,monospace);font-size:0.68rem;color:var(--ink-dim);font-weight:600">ð 2 games · 500 pts</div> 860 </a> 861 862 <a href="game.html?tier=chair" style="display:block;padding:1.5rem;border:1px solid rgba(240,200,80,0.28);border-radius:14px;background:rgba(240,200,80,0.03);text-decoration:none;color:inherit;transition:transform .15s,border-color .15s" onmouseenter="this.style.transform='translateY(-4px)';this.style.borderColor='rgba(240,200,80,0.6)'" onmouseleave="this.style.transform='';this.style.borderColor='rgba(240,200,80,0.28)'"> 863 <div style="font-size:1.8rem;margin-bottom:0.5rem">ðª</div> 864 <div style="font-family:var(--mono,monospace);font-size:0.6rem;letter-spacing:0.18em;color:#f0c850;margin-bottom:0.35rem">TIER 3 · THE LONG GAME</div> 865 <div style="font-size:1.15rem;font-weight:700;color:#f0c850;margin-bottom:0.4rem">CHAIR</div> 866 <div style="font-size:0.82rem;color:var(--ink-dim);line-height:1.5">Full model, historical crises, press, senate, legacy report. The real job.</div> 867 <div style="margin-top:0.9rem;font-family:var(--mono,monospace);font-size:0.68rem;color:var(--ink-dim);font-weight:600">ð 5 games · 650 pts</div> 868 </a> 869 870 <a href="game.html?tier=record&scenario=modern&live=1" style="display:block;padding:1.5rem;border:1px solid rgba(240,200,80,0.28);border-radius:14px;background:rgba(240,200,80,0.03);text-decoration:none;color:inherit;transition:transform .15s,border-color .15s" onmouseenter="this.style.transform='translateY(-4px)';this.style.borderColor='rgba(240,200,80,0.6)'" onmouseleave="this.style.transform='';this.style.borderColor='rgba(240,200,80,0.28)'"> 871 <div style="font-size:1.8rem;margin-bottom:0.5rem">ð</div> 872 <div style="font-family:var(--mono,monospace);font-size:0.6rem;letter-spacing:0.18em;color:#f0c850;margin-bottom:0.35rem">TIER 4 · LIVE ECONOMY</div> 873 <div style="font-size:1.15rem;font-weight:700;color:#f0c850;margin-bottom:0.4rem">GOVERNOR OF RECORD</div> 874 <div style="font-size:0.82rem;color:var(--ink-dim);line-height:1.5">Live FRED sandbox + community leaderboard. Scored against Taylor and the ideal path.</div> 875 <div style="margin-top:0.9rem;font-family:var(--mono,monospace);font-size:0.68rem;color:var(--ink-dim);font-weight:600">ð 10 games · 750 pts · 2 wins</div> 876 </a> 877 878 </div> 879 <p style="margin-top:2rem;font-size:0.8rem;color:var(--ink-dim);font-style:italic">Locks lift automatically as your record grows â progress is saved on this device.</p> 880 </div> 881 </section> 882 883 <!-- ââ MISSION CONTROL BAR (bottom) ââ --> 884 <div id="mission-bar" aria-label="Live simulation status"> 885 <div class="mc-inner"> 886 <div class="mc-live"> 887 <div class="live-dot"></div> 888 LIVE · Q8/20 · MODERN DAY 889 </div> 890 <div class="mc-indicators"> 891 <div class="mc-ind">
892 <span class="mc-label">GDP</span> 893 <span class="mc-val" style="color:#4ade80" id="mc-gdp">+2.4%</span> 894 <span style="color:#4ade80;font-size:0.62rem">â</span> 895 </div> 896 <div class="mc-ind"> 897 <span class="mc-label">INFL</span> 898 <span class="mc-val" style="color:var(--brass-lt)" id="mc-infl">4.1%</span> 899 <span style="color:var(--brass-lt);font-size:0.62rem">â</span> 900 </div> 901 <div class="mc-ind"> 902 <span class="mc-label">UNEMP</span> 903 <span class="mc-val" style="color:var(--ink-dim)" id="mc-unemp">3.9%</span> 904 <span style="color:var(--ink-dim);font-size:0.62rem">â</span> 905 </div> 906 </div> 907 <div class="ticker-wrap"> 908 <div class="ticker-inner"> 909 BLOOMBERG: Fed Chair faces defining quarter amid mixed signals · WSJ: Bond markets clear throat as rate decision looms · r/Economics: "This is the one" â 4.7k upvotes · CNBC: Soft landing probability rises to 32% · FT: 330 million Americans await the rate decision · r/wallstreetbets: Fed Chair about to ruin my puts · BLOOMBERG: Yield curve flattens ahead of FOMC · Sponsored by <span style="color:var(--verdigris)">[Your Brand]</span>: Real-time economic data, precision-grade · BLOOMBERG: Fed Chair faces defining quarter amid mixed signals · WSJ: Bond markets clear throat as rate decision looms · r/Economics: "This is the one" â 4.7k upvotes · CNBC: Soft landing probability rises to 32% · FT: 330 million Americans await the rate decision · 910 </div> 911 </div> 912 </div> 913 </div> 914 915 <!-- ââ MEDIA FEED ââ --> 916 <div class="divider"></div> 917 <section style="padding:4.5rem 1.5rem"> 918 <div class="container"> 919 <div class="section-label reveal" style="text-align:center">Everyone Is Watching You. No Pressure.</div> 920 <div class="media-grid" style="margin-top:2rem"> 921 922 <div class="media-card reveal d1" id="rd-card"> 923 <div style="display:flex;align-items:center;gap:0.6rem;margin-bottom:0.85rem"> 924 <span style="color:#ff6314;font-family:var(--mono);font-size:0.68rem;font-weight:500">r/Economics</span> 925 <span style="color:var(--ink-dim);font-family:var(--mono);font-size:0.6rem">· 2 min ago · 4.7k upvotes</span> 926 </div> 927 <p id="rd-text" style="color:rgba(245,234,216,0.75);font-size:1rem;line-height:1.6;font-style:italic"> 928 "Fed Chair holding steady while inflation creeps up. Bold or reckless? We're watching the next decision like a hawk." 929 </p> 930 <div style="margin-top:0.85rem;font-family:var(--mono);font-size:0.6rem;color:var(--ink-dim);display:flex;gap:1rem"> 931 <span>â 4,718</span><span>ð¬ 892 comments</span> 932 </div> 933 </div> 934 935 <div class="media-card reveal d2" id="bb-card"> 936 <div style="display:flex;align-items:center;gap:0.6rem;margin-bottom:0.85rem"> 937 <span style="background:#1a3aff;color:#fff;font-family:var(--mono);font-size:0.58rem;font-weight:500;padding:0.15rem 0.45rem">BLOOMBERG</span> 938 <span style="color:var(--ink-dim);font-family:var(--mono);font-size:0.6rem">BREAKING · Markets</span> 939 </div> 940 <p id="bb-text" style="color:var(--ink);font-family:var(--serif);font-weight:700;font-size:1.1rem;line-height:1.4"> 941 Markets Rally as Fed Chair Signals Cautious Approach â Dow +340pts 942 </p> 943 <p id="bb-sub" style="margin-top:0.6rem;color:var(--ink-dim);font-size:0.88rem;font-family:var(--serif)"> 944 Bond yields inch lower as traders price in a pause. Every quarter matters. 945 </p> 946 </div> 947 948 <div class="media-card reveal d3"> 949 <div style="display:flex;align-items:center;gap:0.6rem;margin-bottom:0.85rem"> 950 <span style="color:#f59e0b;font-family:var(--mono);font-size:0.68rem;font-weight:500">DR. SARAH CHEN</span>
951 <span style="color:var(--ink-dim);font-family:var(--mono);font-size:0.6rem">Chief Economic Advisor</span> 952 </div> 953 <p style="color:rgba(245,234,216,0.75);font-size:1rem;line-height:1.6;font-style:italic"> 954 "Competent. Disturbingly rare. The yield curve is beginning to take an interest in your decisions." 955 </p> 956 <div style="margin-top:0.85rem;font-family:var(--mono);font-size:0.58rem;color:var(--brass);letter-spacing:0.1em"> 957 QUARTERLY ASSESSMENT · Q8 958 </div> 959 </div> 960 961 </div> 962 </div> 963 </section> 964 965 <!-- ââ WAR ROOM BRIEFING ââ --> 966 <div class="divider"></div> 967 <section id="how-it-works" style="padding:5.5rem 1.5rem"> 968 <div class="container"> 969 <div class="section-label reveal" style="text-align:center">War Room Briefing</div> 970 <h2 class="section-title reveal d1" style="text-align:center;margin-bottom:0.5rem"> 971 Economics you can <span style="color:var(--brass-lt)">feel.</span> 972 </h2> 973 <p class="reveal d2" style="font-family:var(--serif);font-size:1rem;color:var(--ink-dim);text-align:center;max-width:34rem;margin:0 auto 3.5rem;font-style:italic"> 974 Not a textbook. A war room. Real cause-and-effect. Real human consequences. 975 Hover each card for the field briefing. 976 </p> 977 978 <div class="war-room-grid reveal"> 979 980 <!-- Taylor Rule --> 981 <div class="wr-card" onmouseenter="playH(330)"> 982 <div class="wr-label">§ 01</div> 983 <div class="wr-title">Taylor Rule</div> 984 <div class="wr-visual"> 985 <svg viewBox="0 0 200 60" width="100%" height="50" aria-hidden="true"> 986 <text x="0" y="14" font-family="'DM Mono',monospace" font-size="9" fill="rgba(196,144,32,0.8)">r* = rÌ + Ï + 0.5(Ï â Ï*) + 0.5(y â ȳ)</text> 987 <line x1="0" y1="22" x2="200" y2="22" stroke="rgba(196,144,32,0.2)" stroke-width="0.5"/> 988 <circle cx="40" cy="44" r="3" fill="var(--brass)" opacity="0.7"/> 989 <circle cx="80" cy="38" r="3" fill="var(--brass)" opacity="0.7"/> 990 <circle cx="120" cy="30" r="3" fill="var(--brass)" opacity="0.7"/> 991 <circle cx="160" cy="46" r="3" fill="var(--brass)" opacity="0.7"/> 992 <polyline points="40,44 80,38 120,30 160,46" fill="none" stroke="var(--brass)" stroke-width="1.2" opacity="0.5"/> 993 <line x1="0" y1="38" x2="200" y2="38" stroke="var(--verdigris)" stroke-width="0.8" stroke-dasharray="3 2" opacity="0.4"/> 994 <text x="145" y="36" font-family="'DM Mono',monospace" font-size="7" fill="rgba(74,154,143,0.6)">TARGET</text> 995 </svg> 996 </div> 997 <div class="wr-body"> 998 Every Fed Chair's north star. A mathematical benchmark for where rates <em>should</em> be, given inflation and output gaps. 999 </div> 1000 <div class="wr-reveal"> 1001 <div class="wr-tooltip"> 1002 The game tracks your deviation from the Taylor Rule each quarter. Stray too far, and the bond market will notice before you do. 1003 </div> 1004 </div> 1005 </div> 1006 1007 <!-- Phillips Curve --> 1008 <div class="wr-card" onmouseenter="playH(330)"> 1009 <div class="wr-label">§ 02</div> 1010 <div class="wr-title">Phillips Curve</div> 1011 <div class="wr-visual"> 1012 <svg viewBox="0 0 200 60" width="100%" height="50" aria-hidden="true"> 1013 <!-- Inflation axis --> 1014 <text x="2" y="56" font-family="'DM Mono',monospace" font-size="6" fill="rgba(196,144,32,0.5)">UNEMPLOYMENT â</text> 1015 <text x="2" y="8" font-family="'DM Mono',monospace" font-size="6" fill="rgba(196,144,32,0.5)" transform="rotate(-90 8 40)">INFLATION</text> 1016 <!-- Curve: high unemployment = low inflation --> 1017 <path d="M 30,8 Q 90,20 170,52" fill="none" stroke="var(--brass)" stroke-width="1.8" opacity="0.6"/> 1018 <!-- Trade-off zone --> 1019 <circle cx="90" cy="22" r="4" fill="var(--verdigris)" opacity="0.7"/> 1020 <text x="96" y="26" font-family="'DM Mono',monospace" font-size="6.5" fill="rgba(74,154,143,0.8)">SWEET SPOT</text> 1021 </svg> 1022 </div> 1023 <div class="wr-body"> 1024 Inflation and unemployment trade off against each other. Press too hard on one lever and the other breaks. 1025 </div> 1026 <div class="wr-reveal"> 1027 <div class="wr-tooltip"> 1028 The dual mandate lives here. Your job is to stay near the curve's inflection point â not easy when supply shocks rewrite the rules. 1029 </div> 1030 </div> 1031 </div> 1032 1033 <!-- Okun's Law --> 1034 <div class="wr-card" onmouseenter="playH(330)"> 1035 <div class="wr-label">§ 03</div> 1036 <div class="wr-title">Okun's Law</div> 1037 <div class="wr-visual"> 1038 <svg viewBox="0 0 200 60" width="100%" height="50" aria-hidden="true"> 1039 <text x="2" y="8" font-family="'DM Mono',monospace" font-size="7.5" fill="rgba(196,144,32,0.75)">ÎU â â0.5 à (GDP â 2%)</text>
1040 <line x1="0" y1="16" x2="200" y2="16" stroke="rgba(196,144,32,0.15)" stroke-width="0.5"/> 1041 <!-- GDP bar --> 1042 <rect x="10" y="26" width="50" height="8" fill="var(--verdigris)" opacity="0.4" rx="1"/> 1043 <rect x="10" y="26" width="35" height="8" fill="var(--verdigris)" opacity="0.7" rx="1"/> 1044 <text x="66" y="34" font-family="'DM Mono',monospace" font-size="6.5" fill="rgba(74,154,143,0.7)">GDP growth</text> 1045 <!-- Unemployment bar (inverse) --> 1046 <rect x="10" y="44" width="50" height="8" fill="#d44" opacity="0.25" rx="1"/> 1047 <rect x="10" y="44" width="20" height="8" fill="#d44" opacity="0.6" rx="1"/> 1048 <text x="66" y="52" font-family="'DM Mono',monospace" font-size="6.5" fill="rgba(212,68,68,0.7)">Unemployment â</text> 1049 </svg> 1050 </div> 1051 <div class="wr-body"> 1052 GDP growth above trend reduces unemployment. Roughly 1pp of excess GDP trims half a point of joblessness. 1053 </div> 1054 <div class="wr-reveal"> 1055 <div class="wr-tooltip"> 1056 Raise rates too hard, GDP stalls, joblessness climbs. The unemployment line in your chart is Okun's Law made visible in real time. 1057 </div> 1058 </div> 1059 </div> 1060 1061 <!-- Dual Mandate --> 1062 <div class="wr-card" onmouseenter="playH(330)"> 1063 <div class="wr-label">§ 04</div> 1064 <div class="wr-title">Dual Mandate</div> 1065 <div class="wr-visual"> 1066 <svg viewBox="0 0 200 60" width="100%" height="50" aria-hidden="true"> 1067 <!-- Balance beam --> 1068 <line x1="100" y1="18" x2="100" y2="50" stroke="var(--brass)" stroke-width="1.2" opacity="0.5"/> 1069 <circle cx="100" cy="18" r="3" fill="var(--brass)" opacity="0.6"/> 1070 <line x1="30" y1="30" x2="170" y2="30" stroke="var(--brass)" stroke-width="1.4" opacity="0.55"/> 1071 <!-- Left pan: employment --> 1072 <rect x="14" y="32" width="36" height="18" rx="2" fill="var(--surface2)" stroke="var(--verdigris)" stroke-width="0.8" opacity="0.8"/> 1073 <text x="18" y="44" font-family="'DM Mono',monospace" font-size="6" fill="rgba(74,154,143,0.9)">MAX EMP</text> 1074 <!-- Right pan: inflation --> 1075 <rect x="150" y="32" width="36" height="18" rx="2" fill="var(--surface2)" stroke="var(--brass)" stroke-width="0.8" opacity="0.8"/> 1076 <text x="153" y="44" font-family="'DM Mono',monospace" font-size="6" fill="rgba(196,144,32,0.9)">2% INFL</text> 1077 </svg> 1078 </div> 1079 <div class="wr-body"> 1080 Maximum employment and stable prices. Congress gave you two goals that frequently pull in opposite directions. 1081 </div> 1082 <div class="wr-reveal"> 1083 <div class="wr-tooltip"> 1084 Your Legacy Score is measured here. Miss either side consistently and the post-game debrief will be uncomfortable reading. 1085 </div> 1086 </div> 1087 </div> 1088 1089 </div> 1090 </div> 1091 </section> 1092 1093 <!-- ââ SCENARIOS ââ --> 1094 <div class="divider"></div> 1095 <section id="scenarios" style="padding:5.5rem 1.5rem"> 1096 <div class="container"> 1097 <div class="section-label reveal" style="text-align:center">Choose Your Crisis</div> 1098 <h2 class="section-title reveal d1" style="text-align:center;margin-bottom:0.5rem"> 1099 History's <span style="color:#d44">hardest</span> rooms. 1100 </h2> 1101 <p class="reveal d2" style="font-family:var(--serif);font-size:1rem;color:var(--ink-dim);text-align:center;margin-bottom:3.5rem;font-style:italic"> 1102 Most players don't survive. That's the point. 1103 </p> 1104 1105 <div class="sc-grid"> 1106 1107 <!-- Modern Day --> 1108 <div class="sc-card featured reveal d1" 1109 onclick="go('game.html?scenario=modern')" 1110 onmouseenter="scHover(this,event,880)" 1111 role="button" tabindex="0" aria-label="Modern Day scenario"> 1112 <div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:1.25rem">
1113 <span class="badge badge-rookie">ROOKIE</span> 1114 <span class="sc-era">2026</span> 1115 </div> 1116 <div class="sc-name">Modern Day</div> 1117 <p class="sc-desc">Steady economy. Mild inflation. Four governors who already have opinions about you. Learn the controls before the storm arrives.</p> 1118 <div class="sc-survival">67%</div> 1119 <div class="sc-survlabel">Survival Rate</div> 1120 <a href="game.html?scenario=modern" class="btn-primary" style="display:block;text-align:center;width:100%;font-size:0.82rem" onclick="event.stopPropagation();playH(880)">START HERE â</a> 1121 </div> 1122 1123 <!-- COVID --> 1124 <div class="sc-card reveal d2" 1125 onclick="go('game.html?scenario=covid')" 1126 onmouseenter="scHover(this,event,660)" 1127 role="button" tabindex="0"> 1128 <div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:1.25rem"> 1129 <span class="badge badge-analyst">ANALYST</span> 1130 <span class="sc-era dim">2020</span> 1131 </div> 1132 <div class="sc-name">COVID Crash</div> 1133 <p class="sc-desc">Economy in freefall. Cut to zero. Print money. Hope nobody notices the inflation you just created. (They will notice.)</p> 1134 <div class="sc-survival danger">19%</div> 1135 <div class="sc-survlabel">Survival Rate</div> 1136 <a href="game.html?scenario=covid" class="btn-secondary" style="display:block;text-align:center;width:100%;font-size:0.78rem" onclick="event.stopPropagation()">You Were There â</a> 1137 </div> 1138 1139 <!-- 2008 --> 1140 <div class="sc-card reveal d3" 1141 onclick="go('game.html?scenario=2008')" 1142 onmouseenter="scHover(this,event,550)" 1143 role="button" tabindex="0"> 1144 <div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:1.25rem"> 1145 <span class="badge badge-analyst">ANALYST</span> 1146 <span class="sc-era dim">2008</span> 1147 </div> 1148 <div class="sc-name">The Great Recession</div> 1149 <p class="sc-desc">Lehman just fell. The press is outside. The Senate wants a scapegoat. Markets are in freefall. Good morning, Chair.</p> 1150 <div class="sc-survival danger">23%</div> 1151 <div class="sc-survlabel">Survival Rate</div> 1152 <a href="game.html?scenario=2008" class="btn-secondary" style="display:block;text-align:center;width:100%;font-size:0.78rem" onclick="event.stopPropagation()">Take the Risk â</a> 1153 </div> 1154 1155 <!-- Volcker --> 1156 <div class="sc-card reveal d1" 1157 onclick="go('game.html?scenario=1979')" 1158 onmouseenter="scHover(this,event,440)" 1159 role="button" tabindex="0"> 1160 <div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:1.25rem"> 1161 <span class="badge badge-chair">CHAIR</span> 1162 <span class="sc-era dim">1979</span> 1163 </div> 1164 <div class="sc-name">The Volcker Shock</div> 1165 <p class="sc-desc">14% inflation. Volcker hiked to 20% and destroyed unemployment to fix it. History called him a hero. The unemployed were less enthusiastic.</p> 1166 <div class="sc-survival danger">8%</div> 1167 <div class="sc-survlabel">Survival Rate</div> 1168 <a href="game.html?scenario=1979" class="btn-secondary" style="display:block;text-align:center;width:100%;font-size:0.78rem" onclick="event.stopPropagation()">Are You Volcker? â</a> 1169 </div> 1170 1171 <!-- 1929 --> 1172 <div class="sc-card reveal d2" 1173 onclick="go('game.html?scenario=1929')" 1174 onmouseenter="scHover(this,event,330)" 1175 role="button" tabindex="0"> 1176 <div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:1.25rem"> 1177 <span class="badge badge-legend">LEGENDARY</span> 1178 <span class="sc-era dim">1929</span> 1179 </div> 1180 <div class="sc-name">The Great Depression</div> 1181 <p class="sc-desc">You're the last line of defense. 2% of players save it. You will probably not be in that 2%. Play anyway. It's educational.</p> 1182 <div class="sc-survival danger">2%</div> 1183 <div class="sc-survlabel">Survival Rate</div> 1184 <a href="game.html?scenario=1929" class="btn-secondary" style="display:block;text-align:center;width:100%;font-size:0.78rem" onclick="event.stopPropagation()">I'll Try â</a> 1185 </div> 1186 1187 <!-- SPONSORED FEATURED CRISIS --> 1188 <!-- SPONSOR_HOOK: Replace [Partner] and scenario key with actual sponsor data via SPONSOR_CONFIG --> 1189 <div class="sc-card sponsored reveal d3" style="cursor:default"> 1190 <div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:1.25rem">
1191 <span class="badge badge-sponsored">FEATURED CRISIS</span> 1192 <span class="sc-era verd">2026</span> 1193 </div> 1194 <div class="sc-name" style="color:var(--verdigris)">Energy Shock</div> 1195 <p class="sc-desc">Crude spikes to $180. Stagflation knocks. Do you fight inflation or defend growth? No right answer.</p> 1196 <div class="sc-survival" style="color:var(--verdigris)">COMING</div> 1197 <div class="sc-survlabel">In Development</div> 1198 <!-- SPONSOR_HOOK: sponsored-by attribution --> 1199 <div style="margin-top:0.75rem;padding:0.5rem 0.75rem;background:rgba(74,154,143,0.06);border:1px solid rgba(74,154,143,0.18);font-family:var(--mono);font-size:0.58rem;letter-spacing:0.1em;color:rgba(74,154,143,0.7)"> 1200 Featured Crisis â <span style="color:var(--verdigris)">[Partner Name]</span> Economic Research 1201 </div> 1202 </div> 1203 1204 <!-- Live stats card --> 1205 <div class="sc-card reveal d4" style="cursor:default;pointer-events:none;display:flex;flex-direction:column;justify-content:space-between"> 1206 <div> 1207 <div class="section-label" style="margin-bottom:1.5rem">The Fed, In Numbers</div> 1208 <div style="display:flex;flex-direction:column;gap:1.4rem"> 1209 <div> 1210 <div style="font-family:var(--display);font-size:2rem;letter-spacing:0.04em;color:rgba(245,234,216,0.65)">1913</div> 1211 <div class="section-label" style="margin-bottom:0">Federal Reserve Act</div> 1212 </div> 1213 <div> 1214 <div style="font-family:var(--display);font-size:2rem;letter-spacing:0.04em;color:#d44">1977</div> 1215 <div class="section-label" style="margin-bottom:0">Dual Mandate Codified</div> 1216 </div> 1217 <div> 1218 <div style="font-family:var(--display);font-size:2rem;letter-spacing:0.04em;color:var(--brass-lt)">1929</div> 1219 <div class="section-label" style="margin-bottom:0">Hardest Scenario</div> 1220 </div> 1221 </div> 1222 </div> 1223 <div style="margin-top:1.5rem;font-family:var(--serif);font-size:0.8rem;color:var(--ink-dim);font-style:italic;line-height:1.55"> 1224 "Competent. Disturbingly rare."<br>â Dr. Marcus Feldman, Chief Economic Advisor 1225 </div> 1226 </div> 1227 1228 </div> 1229 </div> 1230 </section> 1231 1232 <!-- ââ TESTIMONIALS ââ --> 1233 <div class="divider"></div> 1234 <section style="padding:5rem 1.5rem"> 1235 <div class="container"> 1236 <div class="section-label reveal" style="text-align:center">From the Session</div> 1237 <h2 class="section-title reveal d1" style="text-align:center;margin-bottom:3.5rem"> 1238 What happens when<br>you sit down. 1239 </h2> 1240 <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:1.25rem"> 1241 <div class="testimonial reveal d1"> 1242 <p style="color:rgba(245,234,216,0.65);font-family:var(--serif);font-size:0.92rem;line-height:1.68;font-style:italic;margin-bottom:1.25rem"> 1243 "I never understood why the Fed raises rates during a boom until I watched my GDP line tank when I didn't. It clicked immediately." 1244 </p> 1245 <div style="display:flex;align-items:center;gap:0.75rem"> 1246 <div style="width:34px;height:34px;border-radius:50%;background:#4f46e5;display:flex;align-items:center;justify-content:center;font-size:0.75rem;font-weight:700;flex-shrink:0">E</div> 1247 <div> 1248 <div style="font-family:var(--serif);font-size:0.88rem;font-weight:600">Emma K.</div> 1249 <div style="font-family:var(--mono);font-size:0.62rem;color:var(--ink-dim)">Econ Junior, UMich</div> 1250 </div> 1251 </div> 1252 </div> 1253 <div class="testimonial reveal d2"> 1254 <p style="color:rgba(245,234,216,0.65);font-family:var(--serif);font-size:0.92rem;line-height:1.68;font-style:italic;margin-bottom:1.25rem"> 1255 "I assigned this instead of the Mankiw chapter on monetary policy. Students came to class actually wanting to discuss the Taylor Rule." 1256 </p> 1257 <div style="display:flex;align-items:center;gap:0.75rem"> 1258 <div style="width:34px;height:34px;border-radius:50%;background:#0891b2;display:flex;align-items:center;justify-content:center;font-size:0.75rem;font-weight:700;flex-shrink:0">P</div> 1259 <div> 1260 <div style="font-family:var(--serif);font-size:0.88rem;font-weight:600">
1260Prof. David R.</div> 1261 <div style="font-family:var(--mono);font-size:0.62rem;color:var(--ink-dim)">Macroeconomics, Georgetown</div> 1262 </div> 1263 </div> 1264 </div> 1265 <div class="testimonial reveal d3"> 1266 <p style="color:rgba(245,234,216,0.65);font-family:var(--serif);font-size:0.92rem;line-height:1.68;font-style:italic;margin-bottom:1.25rem"> 1267 "Caused a depression on my first try. Tried 6 more times before I understood inflation targeting. Best 3am of my life." 1268 </p> 1269 <div style="display:flex;align-items:center;gap:0.75rem"> 1270 <div style="width:34px;height:34px;border-radius:50%;background:#16a34a;display:flex;align-items:center;justify-content:center;font-size:0.75rem;font-weight:700;flex-shrink:0">J</div> 1271 <div> 1272 <div style="font-family:var(--serif);font-size:0.88rem;font-weight:600">Jordan M.</div> 1273 <div style="font-family:var(--mono);font-size:0.62rem;color:var(--ink-dim)">Finance MBA, Wharton</div> 1274 </div> 1275 </div> 1276 </div> 1277 </div> 1278 </div> 1279 </section> 1280 1281 <!-- ââ FINAL CTA ââ --> 1282 <div class="divider"></div> 1283 <section style="padding:8rem 1.5rem;text-align:center"> 1284 <div class="container"> 1285 <div class="section-label reveal">The Seat Is Waiting</div> 1286 <h2 class="section-title reveal d1" style="font-size:clamp(3rem,8vw,6rem);letter-spacing:0.06em;margin:1.5rem 0"> 1287 Will you stick the<br><span style="color:var(--brass-lt)">soft landing?</span> 1288 </h2> 1289 <p class="reveal d2" style="font-family:var(--serif);font-size:1.05rem;color:var(--ink-dim);margin-bottom:3rem;font-style:italic"> 1290 Or will 330 million Americans remember your name for the wrong reasons? 1291 </p> 1292 <div class="reveal d3"> 1293 <a href="game.html?scenario=modern" class="btn-primary" style="font-size:1rem;padding:1.2rem 3rem" onmouseenter="playH(660)" onclick="playH(880)"> 1294 TAKE THE CHAIR â FREE. NO ACCOUNT NEEDED. 1295 </a> 1296 </div> 1297 <p class="reveal d4" style="margin-top:1.75rem;font-family:var(--mono);font-size:0.6rem;letter-spacing:0.14em;color:var(--ink-dim)"> 1298 Your economics degree starts here. 1299 </p> 1300 </div> 1301 </section> 1302 1303 <!-- ââ FOOTER ââ --> 1304 <footer> 1305 <!-- SPONSOR_HOOK: Partners in the Machine row â populate via SPONSOR_CONFIG object --> 1306 <div class="container" style="margin-bottom:1.5rem"> 1307 <div class="sponsor-row" id="partner-row"> 1308 <div class="sponsor-label">PARTNERS IN THE MACHINE</div> 1309 <!-- SPONSOR_HOOK: inject partner logos/slots dynamically from SPONSOR_CONFIG --> 1310 <a class="sponsor-slot" href="#" onclick="openSponsorModal('partner1');return false">[Partner Slot 1]</a> 1311 <a class="sponsor-slot" href="#" onclick="openSponsorModal('partner2');return false">[Partner Slot 2]</a> 1312 <a class="sponsor-slot" href="#" onclick="openSponsorModal('partner3');return false">[Partner Slot 3]</a> 1313 </div> 1314 </div> 1315 1316 <!-- Advertising. Explicit unit slot; auto ads also run on this page. The game 1317 screen is excluded from both â see the header of js/ads.js. --> 1318 <div class="container chair-ad-wrap" id="ad-landing"></div> 1319 1320 <!-- Ad-free unlock CTA. Silent until Andrew wires a real Gumroad product â 1321 see the header of js/chair-premium.js. --> 1322 <div class="container" data-adfree-cta style="margin-bottom:1rem;text-align:center"></div> 1323 1324 <!-- Screwcap cross-promo strip --> 1325 <div class="container" id="sc-promo-footer-index" style="margin-bottom:1rem"></div> 1326 1327 <div class="footer-inner"> 1328 <div> 1329 <div class="footer-brand">THE CHAIR</div> 1330 <div style="font-family:var(--mono);font-size:0.72rem;color:var(--ink-dim);margin-top:0.3rem">Simulation only â not financial, economic, or policy advice. ©2026 Screwcap, LLC.</div> 1331 </div> 1332 <nav class="footer-links" aria-label="Footer navigation"> 1333 <a href="game.html">Play</a> 1334 <a href="#scenarios">Scenarios</a> 1335 <a href="changelog.html">Changelog</a> 1336 <a href="sources.html">Sources</a> 1337 <a href="stats.html">Stats</a> 1338 <a href="about.html">About</a> 1339 <a href="terms.html">Terms</a> 1340 <!-- Added 2026-08-24. This footer advertised Terms and nothing else while the 1341 site ran Plausible and had no privacy page at all; /privacy was a 404. --> 1342 <a href="privacy.html">Privacy</a> 1343 <a href="https://screwcap.games">Screwcap Hub</a> 1344 </nav> 1345 </div> 1346 <!-- Attribution for the live strip. Written from the feed rather than typed, so it 1347 cannot describe a set of series the page is no longer showing. --> 1348 <div class="container" id="market-credit" hidden 1349 style="font-family:var(--mono);font-size:0.58rem;letter-spacing:0.06em;color:var(--ink-dim);opacity:0.7;padding-bottom:1rem;text-align:center"></div> 1350 1351 <!-- The Board's Odds â real Polymarket/Kalshi pricing on the next FOMC decision. 1352 Off by default behind a toggle so it doesn't clutter the page for anyone who 1353 just wants to play; on for anyone who wants to see what the actual market 1354 thinks happens next. See api/board-odds.js. --> 1355 <div class="container" id="spicy-zone" style="text-align:center;padding-bottom:1.5rem" hidden> 1356 <button id="spicy-toggle" type="button" aria-expanded="false">ð¶ï¸ Spicy â show The Board's Odds</button> 1357 <div id="board-odds-panel" hidden></div> 1358 </div> 1359 </footer> 1360 1361 <!-- ââ SPONSOR CONFIG â edit this object to update all sponsor hooks ââ --> 1362
1362<script> 1363 // SPONSOR_CONFIG: Single source of truth for all sponsorship placements 1364 // Replace placeholder values when sponsors are onboarded 1365 const SPONSOR_CONFIG = { 1366 ticker: null, // e.g. { name: 'Bloomberg', text: 'Real-time data, precision-grade' } 1367 ratePanel: null, // e.g. { name: 'Refinitiv', label: 'Data provided by Refinitiv' } 1368 consequenceModal: null, // e.g. { name: 'CFA Institute', label: 'Insight by CFA Institute' } 1369 legacyReport: null, // e.g. { name: 'BlackRock', label: 'Simulation enhanced by BlackRock' } 1370 featuredCrisis: null, // e.g. { name: 'ExxonMobil', scenario: 'energy', label: 'ExxonMobil Economic Research' } 1371 partners: [], // e.g. [{ name: 'JPMorgan', url: 'https://...', tagline: '...' }] 1372 }; 1373 1374 function openSponsorModal(id) { 1375 // Placeholder: wire up to actual sponsor data from SPONSOR_CONFIG.partners 1376 } 1377 </script>
1377 1378 1379 <!-- Google Analytics --> 1380 1381 <!-- Service Worker --> 1382
1382<script> 1383 if ('serviceWorker' in navigator) { 1384 window.addEventListener('load', () => navigator.serviceWorker.register('/sw.js').catch(() => {})); 1385 } 1386 </script>
1386 1387 1388
1388<script> 1389 'use strict'; 1390 1391 // ââ NAVIGATION ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 1392 function go(url) { window.location.href = url; } 1393 1394 // ââ WEB AUDIO âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 1395 let _ac = null, _unlocked = false; 1396 document.addEventListener('click', () => { _unlocked = true; if (!_ac) _ac = new (window.AudioContext || window.webkitAudioContext)(); }, { once: true }); 1397 function playH(freq) { 1398 if (!_unlocked || !_ac) return; 1399 try { 1400 const o = _ac.createOscillator(), g = _ac.createGain(); 1401 o.connect(g); g.connect(_ac.destination); 1402 o.type = 'sine'; o.frequency.value = freq; 1403 g.gain.setValueAtTime(0.028, _ac.currentTime); 1404 g.gain.exponentialRampToValueAtTime(0.0001, _ac.currentTime + 0.1); 1405 o.start(_ac.currentTime); o.stop(_ac.currentTime + 0.1); 1406 } catch(e) {} 1407 } 1408 1409 // ââ FILM GRAIN ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 1410 (function() { 1411 const SZ = 128; 1412 const oc = Object.assign(document.createElement('canvas'), { width: SZ, height: SZ }); 1413 const cx = oc.getContext('2d'); 1414 const div = document.getElementById('grain'); 1415 function regen() { 1416 const d = cx.createImageData(SZ, SZ); 1417 for (let i = 0; i < d.data.length; i += 4) { 1418 const v = Math.random() * 255 | 0; 1419 d.data[i] = d.data[i+1] = d.data[i+2] = v; d.data[i+3] = 255; 1420 } 1421 cx.putImageData(d, 0, 0); 1422 div.style.backgroundImage = `url(${oc.toDataURL()})`; 1423 } 1424 regen(); 1425 setInterval(regen, 80); 1426 })(); 1427 1428 // ââ NAV SCROLL STATE âââââââââââââââââââââââââââââââââââââââââââââââââââââ 1429 const nav = document.getElementById('navbar'); 1430 window.addEventListener('scroll', () => nav.classList.toggle('scrolled', scrollY > 60), { passive: true }); 1431 1432 // ââ SCROLL REVEAL âââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 1433 const ro = new IntersectionObserver(entries => { 1434 entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('in'); ro.unobserve(e.target); }}); 1435 }, { threshold: 0.1 }); 1436 document.querySelectorAll('.reveal').forEach(el => ro.observe(el)); 1437 1438 // ââ COUNTER ANIMATIONS ââââââââââââââââââââââââââââââââââââââââââââââââââââ 1439 function animCount(el, target, dur, prefix, suffix) { 1440 if (!el) return; 1441 const obs = new IntersectionObserver(([e]) => { 1442 if (!e.isIntersecting) return; obs.disconnect(); 1443 const fmt = v => Math.round(v).toLocaleString('en-US'); 1444 let t0 = null; 1445 function step(ts) { 1446 if (!t0) t0 = ts; 1447 const p = Math.min((ts - t0) / dur, 1); 1448 const ease = 1 - Math.pow(1 - p, 3); 1449 el.textContent = (prefix || '') + fmt(target * ease) + (suffix || ''); 1450 if (p < 1) requestAnimationFrame(step); 1451 } 1452 requestAnimationFrame(step); 1453 }, { threshold: 0.4 }); 1454 obs.observe(el); 1455 } 1456 1457 // Live 10-year Treasury via /api/treasury (FRED DGS10, key held server-side). 1458 // If the feed is unavailable the nav keeps the dual-mandate line it already shows â 1459 // it never renders a placeholder rate, which is the entire point of the 7 Aug change. 1460 (function () { 1461 const el = document.getElementById('nav-ust'); 1462 if (!el) return; 1463 fetch('/api/treasury') 1464 .then(r => r.json()) 1465 .then(d => { 1466 if (!d || !d.ok || typeof d.value !== 'number') return; // leave the fallback 1467 el.innerHTML = 'US 10Y: <span style="color:var(--verdigris)">' + 1468 d.value.toFixed(2) + '%</span> <span style="opacity:.55">as of ' + d.asOf + '</span>'; 1469 }) 1470 .catch(() => { /* keep the fallback */ }); 1471 })(); 1472 1473 // The macro strip along the top, from /api/markets (FRED, key held server-side). 1474 // Renders real prints with their as-of dates, or stays hidden. Never a constant. 1475 (function () { 1476 const rail = document.getElementById('top-ticker-scroll'); 1477 const wrap = document.getElementById('top-ticker'); 1478 if (!rail || !wrap) return; 1479 fetch('/api/markets') 1480 .then(r => r.json()) 1481 .then(d => { 1482 if (!d || !d.ok || !Array.isArray(d.items) || !d.items.length) return; // stay hidden 1483 const esc = s => String(s).replace(/[&<>"]/g, c => ({ '&':'&','<':'<','>':'>','"':'"' }[c])); 1484 const item = it => 1485 '<span class="tt-item" title="FRED ' + esc(it.series) + ' â as of ' + esc(it.asOf) + '">' + 1486 '<span class="tt-sym">
1486' + esc(it.label) + '</span>' + 1487 '<span class="tt-val">' + esc(it.text) + '</span>' + 1488 '<span class="tt-sep">|</span>' + 1489 '</span>'; 1490 const once = d.items.map(item).join(''); 1491 // Doubled so the marquee loops seamlessly, exactly as the static markup did. 1492 rail.innerHTML = once + once; 1493 wrap.hidden = false; 1494 1495 /* Attribution. The index levels are somebody's marks and the deal for showing 1496 them is that you say whose they are â so the credit line is rendered from the 1497 data rather than typed in, and it cannot go stale if the strip changes. */ 1498 const credit = document.getElementById('market-credit'); 1499 if (credit) { 1500 const owners = [...new Set(d.items.map(i => i.source).filter(Boolean))]; 1501 credit.textContent = 'Live figures: ' + owners.join(' · ') + 1502 ' â retrieved via FRED, Federal Reserve Bank of St. Louis. Index levels are ' + 1503 'reported for information and are the property of their owners. See Sources.'; 1504 credit.hidden = false; 1505 } 1506 }) 1507 .catch(() => { /* stay hidden */ }); 1508 })(); 1509 1510 // Real Fed news, delayed 1-2h on purpose (api/fed-news.js). Framed as the desk's own 1511 // running joke about the delay rather than hidden â "we're a little behind too" fits 1512 // the room better than pretending to be a live wire. 1513 (function () { 1514 const rail = document.getElementById('fed-news-scroll'); 1515 const wrap = document.getElementById('fed-news-ticker'); 1516 if (!rail || !wrap) return; 1517 fetch('/api/fed-news') 1518 .then(r => r.json()) 1519 .then(d => { 1520 if (!d || !d.ok || !Array.isArray(d.items) || !d.items.length) return; // stay hidden 1521 const esc = s => String(s).replace(/[&<>"]/g, c => ({ '&':'&','<':'<','>':'>','"':'"' }[c])); 1522 const item = it => '<a class="tt-item" href="' + esc(it.link || '#') + '" target="_blank" rel="noopener noreferrer" ' + 1523 'style="text-decoration:none" title="Federal Reserve â ' + esc(it.publishedAt) + '">' + 1524 '<span class="fn-age">ð ' + it.ageHours + 'h ago</span>' + 1525 '<span class="fn-text">' + esc(it.title) + '</span>' + 1526 '<span class="tt-sep">|</span>' + 1527 '</a>'; 1528 const once = d.items.map(item).join(''); 1529 rail.innerHTML = once + once; 1530 wrap.hidden = false; 1531 }) 1532 .catch(() => { /* stay hidden */ }); 1533 })(); 1534 1535 // The Board's Odds â real Polymarket/Kalshi pricing, revealed by the ð¶ï¸ Spicy toggle. 1536 (function () { 1537 const zone = document.getElementById('spicy-zone'); 1538 const btn = document.getElementById('spicy-toggle'); 1539 const panel = document.getElementById('board-odds-panel'); 1540 if (!zone || !btn || !panel) return; 1541 1542 const LABELS = { 1543 '50+ bps decrease': 'Big cut (50bps+)', '25 bps decrease': 'Cut 25bps', 1544 'No change': 'Hold', '25 bps increase': 'Hike 25bps', '50+ bps increase': 'Big hike (50bps+)', 1545 }; 1546 const esc = s => String(s).replace(/[&<>"]/g, c => ({ '&':'&','<':'<','>':'>','"':'"' }[c])); 1547 let loaded = false, expanded = false; 1548 1549 function render(d) { 1550 if (!d.poly && !d.kalshi) { zone.hidden = true; return; } 1551 let html = ''; 1552 if (d.poly) { 1553 html += '<h4>' + esc(d.poly.title) + '</h4>'; 1554 for (const o of d.poly.outcomes) { 1555 const pct = Math.round(o.yesProb * 1000) / 10; 1556 html += '<div class="bo-row"><span>' + esc(LABELS[o.label] || o.label) + '</span>' + 1557 '<span class="bo-bar-wrap"><span class="bo-bar" style="width:' + pct + '%"></span></span>' + 1558 '<span>' + pct + '%</span></div>'; 1559 } 1560 } 1561 let src = []; 1562 if (d.poly) src.push('<a href="' + esc(d.poly.url) + '" target="_blank" rel="noopener noreferrer">Polymarket</a>'); 1563 if (d.kalshi) src.push('Kalshi corroborates: ' + esc(d.kalshi.meeting) + ', ' + 1564 Math.round(d.kalshi.impliedNo * 1000) / 10 + '% chance the rate stays at/below ' + 1565 esc(d.kalshi.strike) + ' (<a href="' + esc(d.kalshi.url) + '" target="_blank" rel="noopener noreferrer">Kalshi</a>)'); 1566 if (src.length) html += '<div class="bo-source">Real-money markets, not us: ' + src.join(' · ') + '</div>'; 1567 panel.innerHTML = html; 1568 } 1569 1570 btn.addEventListener('click', function () { 1571 expanded = !expanded; 1572 panel.hidden = !expanded; 1573 btn.setAttribute('aria-expanded', String(expanded)); 1574 btn.textContent = expanded ? 'ð¶ï¸ Hide The Board\'s Odds' : 'ð¶ï¸ Spicy â show The Board\'s Odds'; 1575 if (expanded && !loaded) { 1576 loaded = true; 1577 fetch('/api/board-odds').then(r => r.json()).then(d => { 1578 if (!d || !d.ok) { zone.hidden = true; return; } 1579 render(d); 1580 }).catch(() => { zone.hidden = true; }); 1581 } 1582 }); 1583 1584 // The toggle itself only shows up once we know there's real data behind it â 1585 // same "no dead buttons" rule as the rest of this page's live features. 1586 fetch('/api/board-odds').then(r => r.json()).then(d => {
1587 if (d && d.ok && (d.poly || d.kalshi)) zone.hidden = false; 1588 }).catch(() => {}); 1589 })(); 1590 1591 // Invented usage counters removed 7 Aug: players=14872, streak=41, games=312884, all 1592 // hardcoded and animated to look measured. The page contradicted itself â the nav 1593 // claimed 105,847 players while this block claimed 14,872. Replaced with facts about 1594 // the Fed, which are true, thematic, and need no telemetry. Real usage numbers belong 1595 // in the Partner/advertising material once they exist and can be substantiated. 1596 1597 // Nav counters removed 7 Aug. They were hardcoded (142 economists, 105,847 players) 1598 // and random-walked upward on a 6s interval to simulate live activity, with no data 1599 // source of any kind. Presenting that under a "LIVE" label to an audience of finance 1600 // professionals and attorneys is a claim the product cannot support. Replace with the 1601 // real 10-year Treasury (FRED DGS10, cached daily) when a key is available. 1602 1603 // ââ SCENARIO HOVER SOUND âââââââââââââââââââââââââââââââââââââââââââââââââ 1604 function scHover(el, e, freq) { playH(freq); } 1605 1606 // ââ BACKGROUND CANVAS (economic chart atmosphere) âââââââââââââââââââââââââ 1607 (function() { 1608 const canvas = document.getElementById('bg-canvas'); 1609 const ctx = canvas.getContext('2d'); 1610 let W, H; 1611 function resize() { W = canvas.width = canvas.offsetWidth; H = canvas.height = canvas.offsetHeight; } 1612 window.addEventListener('resize', resize, { passive: true }); resize(); 1613 const lines = [ 1614 { pts: [], color: 'rgba(196,144,32,', speed: 0.18, amp: 28, freq: 0.012 }, 1615 { pts: [], color: 'rgba(74,154,143,', speed: 0.12, amp: 20, freq: 0.018 }, 1616 { pts: [], color: 'rgba(196,144,32,', speed: 0.22, amp: 16, freq: 0.022 }, 1617 ]; 1618 let t = 0; 1619 function draw() { 1620 ctx.clearRect(0, 0, W, H); 1621 t += 0.4; 1622 lines.forEach((line, li) => { 1623 ctx.beginPath(); 1624 const n = Math.ceil(W / 18) + 1; 1625 const yBase = H * (0.35 + li * 0.22); 1626 for (let i = 0; i < n; i++) { 1627 const x = i * 18; 1628 const y = yBase + Math.sin((i * line.freq + t * line.speed) * 2 * Math.PI) * line.amp; 1629 if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y); 1630 } 1631 const g = ctx.createLinearGradient(0, yBase - line.amp, 0, yBase + line.amp); 1632 g.addColorStop(0, line.color + '0.07)'); 1633 g.addColorStop(0.5, line.color + '0.13)'); 1634 g.addColorStop(1, line.color + '0.03)'); 1635 ctx.strokeStyle = g; 1636 ctx.lineWidth = 1.2; 1637 ctx.stroke(); 1638 }); 1639 requestAnimationFrame(draw); 1640 } 1641 draw(); 1642 })(); 1643 1644 // ââ GSAP (after load) âââââââââââââââââââââââââââââââââââââââââââââââââââââ 1645 window.addEventListener('load', () => { 1646 if (typeof gsap === 'undefined') return; 1647 1648 // Hero title metallic shimmer 1649 gsap.fromTo('.hero-title .chair', 1650 { textShadow: '0 0 40px rgba(232,184,64,0.3)' }, 1651 { textShadow: '0 0 80px rgba(232,184,64,0.6), 0 0 160px rgba(196,144,32,0.25)', duration: 2.8, repeat: -1, yoyo: true, ease: 'sine.inOut' } 1652 ); 1653 1654 // Stat cells stagger reveal 1655 gsap.from('.stat-cell', { 1656 opacity: 0, y: 18, stagger: 0.12, duration: 0.7, ease: 'power2.out', delay: 0.6 1657 }); 1658 1659 // War room card left-border glow pulse 1660 document.querySelectorAll('.wr-card').forEach((card, i) => { 1661 gsap.to(card.querySelector ? card : card, { 1662 boxShadow: 'inset 2px 0 0 rgba(196,144,32,0.08)', duration: 2 + i * 0.4, repeat: -1, yoyo: true, ease: 'sine.inOut', delay: i * 0.3 1663 }); 1664 }); 1665 }); 1666 1667 </script>
1667 1668 1669
1669<script src="js/chair-premium.js?v=1"></script>
1669 1670
1670<script src="js/ads.js?v=303"></script>
1670 1671
1671<script src="js/screwcap-promo.js?v=1"></script>
1671 1672
1672<script src="js/progression/tiers.js?v=1"></script>
1672 1673
1673<script> 1674 document.addEventListener('DOMContentLoaded', () => { 1675 ScrewcapPromo.inject('sc-promo-footer-index', { currentGame: 'the-chair' }); 1676 1677 // Career ladder: unlock tier cards the player has actually earned. 1678 try { 1679 if (window.TierProgression) { 1680 const prog = new TierProgression(); 1681 document.querySelectorAll('#ladder a[href*="tier="]').forEach(card => { 1682 const m = card.getAttribute('href').match(/tier=(\w+)/); 1683 const id = m && (m[1] === 'record' ? 'record' : m[1]); 1684 if (id && prog.isUnlocked(id)) { 1685 const badge = card.querySelector('div:last-child'); 1686 if (badge) { badge.textContent = 'ENTER â'; badge.style.color = 'var(--verdigris)'; } 1687 card.style.borderColor = 'rgba(0,191,165,0.35)'; 1688 card.style.background = 'rgba(0,191,165,0.04)'; 1689 } 1690 }); 1691 } 1692 } catch (e) { /* landing degrades gracefully */ } 1693 }); 1694 </script>
1694 1695 1696 <!-- Buy Me a Coffee --> 1697
1697<script data-name="BMC-Widget" data-cfasync="false" 1698 src="https://cdnjs.buymeacoffee.com/1.0.0/widget.prod.min.js" 1699 data-id="thechair" data-description="Enjoyed THE CHAIR?" 1700 data-message="Help keep the Fed funded!" data-color="#c49020" 1701 data-position="Right" data-x_margin="18" data-y_margin="18"></script>
1701 1702 1703</body> 1704</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.