PageSourceSearch

https://thechair.vercel.app/

html thechair.vercel.app collected 2026-10-03 07:52:02 UTC 91,071 bytes, 1,704 lines download raw bytes

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 &amp; MAXIMUM EMPLOYMENT">DUAL MANDATE: <span style="color:var(--verdigris)">PRICE STABILITY</span> &amp; <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 &nbsp;·&nbsp; FEDERAL RESERVE SYSTEM &nbsp;·&nbsp; 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 &nbsp;·&nbsp; WSJ: Bond markets clear throat as rate decision looms &nbsp;·&nbsp; r/Economics: "This is the one" — 4.7k upvotes &nbsp;·&nbsp; CNBC: Soft landing probability rises to 32% &nbsp;·&nbsp; FT: 330 million Americans await the rate decision &nbsp;·&nbsp; r/wallstreetbets: Fed Chair about to ruin my puts &nbsp;·&nbsp; BLOOMBERG: Yield curve flattens ahead of FOMC &nbsp;·&nbsp; Sponsored by <span style="color:var(--verdigris)">[Your Brand]</span>: Real-time economic data, precision-grade &nbsp;·&nbsp; BLOOMBERG: Fed Chair faces defining quarter amid mixed signals &nbsp;·&nbsp; WSJ: Bond markets clear throat as rate decision looms &nbsp;·&nbsp; r/Economics: "This is the one" — 4.7k upvotes &nbsp;·&nbsp; CNBC: Soft landing probability rises to 32% &nbsp;·&nbsp; FT: 330 million Americans await the rate decision &nbsp;·&nbsp;
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 => ({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;' }[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 => ({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;' }[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 => ({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;' }[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.