1+ <!-- _includes/gate.html -->
2+ < script >
3+ ( function ( ) {
4+ // --- Config ---
5+ var QUESTION = "Riddle: What has keys but can't open locks?" ;
6+ var ACCEPTED = [ "piano" ] ;
7+ var FORCE_THREE_IF_FIRST_FAIL = true ;
8+
9+ // Unique per page using the URL path
10+ var STORAGE_KEY = "gatePassed:" + location . pathname ;
11+
12+ if ( sessionStorage . getItem ( STORAGE_KEY ) === "1" ) return ;
13+
14+ var restoreOverflow = document . documentElement . style . overflow ;
15+ document . documentElement . style . overflow = "hidden" ;
16+
17+ var overlay = document . createElement ( "div" ) ;
18+ var html =
19+ '<style>' +
20+ '.gate-overlay{position:fixed;inset:0;display:grid;place-items:center;' +
21+ ' background:rgba(0,0,0,.88);z-index:9999;font-family:sans-serif;transition:opacity .2s ease}' +
22+ '.gate-overlay.fade{opacity:0;pointer-events:none}' +
23+ '.gate-card{background:#111;color:#eee;padding:24px;border-radius:14px;' +
24+ ' width:min(90vw,420px);text-align:center;box-shadow:0 10px 25px rgba(0,0,0,.4)}' +
25+ '.gate-input{width:90%;padding:10px;border-radius:8px;border:1px solid #555;' +
26+ ' background:#222;color:#fff;margin-top:12px}' +
27+ '.gate-btn{margin-top:14px;padding:10px 16px;border:0;border-radius:8px;' +
28+ ' background:#2563eb;color:#fff;font-weight:bold;cursor:pointer}' +
29+ '.msg{margin-top:10px;font-size:.95rem;min-height:1.2em}' +
30+ '</style>' +
31+ '<div class="gate-overlay" role="dialog" aria-modal="true" aria-labelledby="gate-title">' +
32+ ' <div class="gate-card">' +
33+ ' <h2 id="gate-title">Answer this to enter</h2>' +
34+ ' <p>' + QUESTION . replace ( / < / g, "<" ) + '</p>' +
35+ ' <input class="gate-input" type="text" placeholder="Your answer..." aria-label="Your answer" />' +
36+ ' <button class="gate-btn" type="button">Submit</button>' +
37+ ' <div class="msg" aria-live="polite"></div>' +
38+ ' </div>' +
39+ '</div>' ;
40+ overlay . innerHTML = html ;
41+ document . body . appendChild ( overlay ) ;
42+
43+ var gate = overlay . querySelector ( ".gate-overlay" ) ;
44+ var input = overlay . querySelector ( ".gate-input" ) ;
45+ var btn = overlay . querySelector ( ".gate-btn" ) ;
46+ var msg = overlay . querySelector ( ".msg" ) ;
47+
48+ setTimeout ( function ( ) { if ( input ) input . focus ( ) ; } , 10 ) ;
49+
50+ var tries = 0 , firstWrong = false ;
51+ function normalize ( s ) { return ( s || "" ) . trim ( ) . toLowerCase ( ) ; }
52+
53+ function done ( ) {
54+ sessionStorage . setItem ( STORAGE_KEY , "1" ) ;
55+ gate . classList . add ( "fade" ) ;
56+ setTimeout ( function ( ) {
57+ overlay . remove ( ) ;
58+ document . documentElement . style . overflow = restoreOverflow || "" ;
59+ } , 220 ) ;
60+ }
61+
62+ function handleSubmit ( ) {
63+ var ok = ACCEPTED . indexOf ( normalize ( input . value ) ) !== - 1 ;
64+ tries ++ ;
65+
66+ if ( tries === 1 && ok ) return done ( ) ;
67+ if ( tries === 1 && ! ok ) firstWrong = true ;
68+
69+ if ( firstWrong && FORCE_THREE_IF_FIRST_FAIL && tries < 3 ) {
70+ var left = 3 - tries ;
71+ msg . textContent = ok
72+ ? "Correct, but you must submit " + left + " more " + ( left === 1 ? "time" : "times" ) + "!"
73+ : "Nope. " + left + " " + ( left === 1 ? "try" : "tries" ) + " left." ;
74+ input . select ( ) ;
75+ return ;
76+ }
77+
78+ if ( firstWrong && FORCE_THREE_IF_FIRST_FAIL && tries === 3 ) return done ( ) ;
79+
80+ if ( ok ) return done ( ) ;
81+ msg . textContent = "Try again." ;
82+ input . select ( ) ;
83+ }
84+
85+ btn . addEventListener ( "click" , handleSubmit ) ;
86+ input . addEventListener ( "keydown" , function ( e ) {
87+ if ( e . key === "Enter" ) { e . preventDefault ( ) ; handleSubmit ( ) ; }
88+ } ) ;
89+ } ) ( ) ;
90+ </ script >
91+
92+ < noscript >
93+ < div style ="padding:1rem;background:#fee2e2;border:1px solid #fecaca;border-radius:8px;color:#7f1d1d;margin:.75rem 0; ">
94+ JavaScript is required to view this page.
95+ </ div >
96+ </ noscript >
0 commit comments