Clean up unused files and tracked junk
CI / regression (push) Successful in 2m33s

Remove the duplicate fancy-wordle-modern.html page, the standalone intro
prototype, the CSS backup and an unused image. Stop tracking .DS_Store and
Playwright MCP logs, and refresh IMPROVEMENTS.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Zakaria
2026-10-28 10:39:44 -04:00
parent 6daf3237e8
commit 931176b0c6
20 changed files with 8 additions and 1639 deletions
Vendored
BIN
View File
Binary file not shown.
+2
View File
@@ -2,3 +2,5 @@ node_modules/
playwright-report/
test-results/
.hermes/
.DS_Store
.playwright-mcp/
@@ -1,2 +0,0 @@
[ 242ms] [VERBOSE] [DOM] Multiple forms should be contained in their own form elements; break up complex forms into ones that represent a single action: (More info: https://goo.gl/9p2vKq) %o @ https://wordle.zackvps.fun/:0
[ 255ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ https://wordle.zackvps.fun/favicon.ico:0
@@ -1 +0,0 @@
[ 88ms] [VERBOSE] [DOM] Multiple forms should be contained in their own form elements; break up complex forms into ones that represent a single action: (More info: https://goo.gl/9p2vKq) %o @ https://wordle.zackvps.fun/:0
@@ -1 +0,0 @@
[ 83ms] [VERBOSE] [DOM] Multiple forms should be contained in their own form elements; break up complex forms into ones that represent a single action: (More info: https://goo.gl/9p2vKq) %o @ https://wordle.zackvps.fun/:0
@@ -1,7 +0,0 @@
[ 63ms] [VERBOSE] [DOM] Multiple forms should be contained in their own form elements; break up complex forms into ones that represent a single action: (More info: https://goo.gl/9p2vKq) %o @ https://wordle.zackvps.fun/:0
[ 57103ms] [VERBOSE] [DOM] Multiple forms should be contained in their own form elements; break up complex forms into ones that represent a single action: (More info: https://goo.gl/9p2vKq) %o @ https://wordle.zackvps.fun/:0
[ 128589ms] [VERBOSE] [DOM] Multiple forms should be contained in their own form elements; break up complex forms into ones that represent a single action: (More info: https://goo.gl/9p2vKq) %o @ https://wordle.zackvps.fun/:0
[ 159498ms] [VERBOSE] [DOM] Multiple forms should be contained in their own form elements; break up complex forms into ones that represent a single action: (More info: https://goo.gl/9p2vKq) %o @ https://wordle.zackvps.fun/:0
[ 181084ms] [VERBOSE] [DOM] Multiple forms should be contained in their own form elements; break up complex forms into ones that represent a single action: (More info: https://goo.gl/9p2vKq) %o @ https://wordle.zackvps.fun/:0
[ 183833ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ https://wordle.zackvps.fun/favicon.ico:0
[ 223939ms] [VERBOSE] [DOM] Multiple forms should be contained in their own form elements; break up complex forms into ones that represent a single action: (More info: https://goo.gl/9p2vKq) %o @ https://wordle.zackvps.fun/:0
@@ -1,5 +0,0 @@
[ 101ms] [VERBOSE] [DOM] Multiple forms should be contained in their own form elements; break up complex forms into ones that represent a single action: (More info: https://goo.gl/9p2vKq) %o @ https://wordle.zackvps.fun/:0
[ 24765ms] [VERBOSE] [DOM] Multiple forms should be contained in their own form elements; break up complex forms into ones that represent a single action: (More info: https://goo.gl/9p2vKq) %o @ https://wordle.zackvps.fun/:0
[ 27174ms] [ERROR] Failed to load resource: the server responded with a status of 400 () @ https://bxrrirbaucroteyumeul.supabase.co/auth/v1/token?grant_type=password:0
[ 28036ms] [ERROR] Failed to load resource: the server responded with a status of 400 () @ https://bxrrirbaucroteyumeul.supabase.co/auth/v1/token?grant_type=password:0
[ 122326ms] [ERROR] Failed to load resource: the server responded with a status of 400 () @ https://bxrrirbaucroteyumeul.supabase.co/auth/v1/token?grant_type=password:0
@@ -1,88 +0,0 @@
- generic [ref=e2]:
- banner "Game controls" [ref=e3]:
- link "Restart Fancy Wordle" [ref=e4] [cursor=pointer]:
- /url: "#"
- generic [ref=e5]: W
- generic [ref=e6]:
- strong [ref=e7]: Fancy Wordle
- text: One word every hour
- navigation "Quick actions" [ref=e8]:
- button "Toggle dark mode" [ref=e9] [cursor=pointer]:
- generic [ref=e10]: ◐
- button "Open stats and share" [ref=e11] [cursor=pointer]:
- generic [ref=e12]: ↗
- button "Open hourly leaderboard" [ref=e13] [cursor=pointer]:
- generic [ref=e14]: ♛
- button "Sign in to sync stats" [ref=e15] [cursor=pointer]: Sign in
- link "Open the original love note" [ref=e16] [cursor=pointer]:
- /url: https://www.youtube.com/watch?v=UkOKCWDJ4iA
- generic [ref=e17]: ♡
- main [ref=e18]:
- region "Guess the word in six tries." [ref=e19]:
- paragraph [ref=e20]: Hourly challenge
- heading "Guess the word in six tries." [level=1] [ref=e21]
- paragraph [ref=e22]: Play one five-letter word per hour. Valid words reveal with smooth flips, warm feedback, confetti, sound, and a definition at the end.
- region "Wordle game board" [ref=e23]:
- generic [ref=e24]:
- generic [ref=e25]: Loading word lists…
- generic [ref=e26]: 0 / 6
- generic "Guess grid" [ref=e27]:
- img "Empty letter" [ref=e28]
- img "Empty letter" [ref=e29]
- img "Empty letter" [ref=e30]
- img "Empty letter" [ref=e31]
- img "Empty letter" [ref=e32]
- img "Empty letter" [ref=e33]
- img "Empty letter" [ref=e34]
- img "Empty letter" [ref=e35]
- img "Empty letter" [ref=e36]
- img "Empty letter" [ref=e37]
- img "Empty letter" [ref=e38]
- img "Empty letter" [ref=e39]
- img "Empty letter" [ref=e40]
- img "Empty letter" [ref=e41]
- img "Empty letter" [ref=e42]
- img "Empty letter" [ref=e43]
- img "Empty letter" [ref=e44]
- img "Empty letter" [ref=e45]
- img "Empty letter" [ref=e46]
- img "Empty letter" [ref=e47]
- img "Empty letter" [ref=e48]
- img "Empty letter" [ref=e49]
- img "Empty letter" [ref=e50]
- img "Empty letter" [ref=e51]
- img "Empty letter" [ref=e52]
- img "Empty letter" [ref=e53]
- img "Empty letter" [ref=e54]
- img "Empty letter" [ref=e55]
- img "Empty letter" [ref=e56]
- img "Empty letter" [ref=e57]
- generic "Keyboard" [ref=e58]:
- button "Q" [ref=e59] [cursor=pointer]
- button "W" [ref=e60] [cursor=pointer]
- button "E" [ref=e61] [cursor=pointer]
- button "R" [ref=e62] [cursor=pointer]
- button "T" [ref=e63] [cursor=pointer]
- button "Y" [ref=e64] [cursor=pointer]
- button "U" [ref=e65] [cursor=pointer]
- button "I" [ref=e66] [cursor=pointer]
- button "O" [ref=e67] [cursor=pointer]
- button "P" [ref=e68] [cursor=pointer]
- button "A" [ref=e69] [cursor=pointer]
- button "S" [ref=e70] [cursor=pointer]
- button "D" [ref=e71] [cursor=pointer]
- button "F" [ref=e72] [cursor=pointer]
- button "G" [ref=e73] [cursor=pointer]
- button "H" [ref=e74] [cursor=pointer]
- button "J" [ref=e75] [cursor=pointer]
- button "K" [ref=e76] [cursor=pointer]
- button "L" [ref=e77] [cursor=pointer]
- button "Enter" [ref=e78] [cursor=pointer]
- button "Z" [ref=e79] [cursor=pointer]
- button "X" [ref=e80] [cursor=pointer]
- button "C" [ref=e81] [cursor=pointer]
- button "V" [ref=e82] [cursor=pointer]
- button "B" [ref=e83] [cursor=pointer]
- button "N" [ref=e84] [cursor=pointer]
- button "M" [ref=e85] [cursor=pointer]
- button "Delete letter" [ref=e86] [cursor=pointer]: ⌫
@@ -1,88 +0,0 @@
- generic [ref=e2]:
- banner "Game controls" [ref=e3]:
- link "Restart Fancy Wordle" [ref=e4] [cursor=pointer]:
- /url: "#"
- generic [ref=e5]: W
- generic [ref=e6]:
- strong [ref=e7]: Fancy Wordle
- text: One word every hour
- navigation "Quick actions" [ref=e8]:
- button "Toggle dark mode" [ref=e9] [cursor=pointer]:
- generic [ref=e10]: ◐
- button "Open stats and share" [ref=e11] [cursor=pointer]:
- generic [ref=e12]: ↗
- button "Open hourly leaderboard" [ref=e13] [cursor=pointer]:
- generic [ref=e14]: ♛
- button "Sign in to sync stats" [ref=e15] [cursor=pointer]: Sign in
- link "Open the original love note" [ref=e16] [cursor=pointer]:
- /url: https://www.youtube.com/watch?v=UkOKCWDJ4iA
- generic [ref=e17]: ♡
- main [ref=e18]:
- region "Guess the word in six tries." [ref=e19]:
- paragraph [ref=e20]: Hourly challenge
- heading "Guess the word in six tries." [level=1] [ref=e21]
- paragraph [ref=e22]: Play one five-letter word per hour. Valid words reveal with smooth flips, warm feedback, confetti, sound, and a definition at the end.
- region "Wordle game board" [ref=e23]:
- generic [ref=e24]:
- generic [ref=e25]: Loading word lists…
- generic [ref=e26]: 0 / 6
- generic "Guess grid" [ref=e27]:
- img "Empty letter" [ref=e28]
- img "Empty letter" [ref=e29]
- img "Empty letter" [ref=e30]
- img "Empty letter" [ref=e31]
- img "Empty letter" [ref=e32]
- img "Empty letter" [ref=e33]
- img "Empty letter" [ref=e34]
- img "Empty letter" [ref=e35]
- img "Empty letter" [ref=e36]
- img "Empty letter" [ref=e37]
- img "Empty letter" [ref=e38]
- img "Empty letter" [ref=e39]
- img "Empty letter" [ref=e40]
- img "Empty letter" [ref=e41]
- img "Empty letter" [ref=e42]
- img "Empty letter" [ref=e43]
- img "Empty letter" [ref=e44]
- img "Empty letter" [ref=e45]
- img "Empty letter" [ref=e46]
- img "Empty letter" [ref=e47]
- img "Empty letter" [ref=e48]
- img "Empty letter" [ref=e49]
- img "Empty letter" [ref=e50]
- img "Empty letter" [ref=e51]
- img "Empty letter" [ref=e52]
- img "Empty letter" [ref=e53]
- img "Empty letter" [ref=e54]
- img "Empty letter" [ref=e55]
- img "Empty letter" [ref=e56]
- img "Empty letter" [ref=e57]
- generic "Keyboard" [ref=e58]:
- button "Q" [ref=e59] [cursor=pointer]
- button "W" [ref=e60] [cursor=pointer]
- button "E" [ref=e61] [cursor=pointer]
- button "R" [ref=e62] [cursor=pointer]
- button "T" [ref=e63] [cursor=pointer]
- button "Y" [ref=e64] [cursor=pointer]
- button "U" [ref=e65] [cursor=pointer]
- button "I" [ref=e66] [cursor=pointer]
- button "O" [ref=e67] [cursor=pointer]
- button "P" [ref=e68] [cursor=pointer]
- button "A" [ref=e69] [cursor=pointer]
- button "S" [ref=e70] [cursor=pointer]
- button "D" [ref=e71] [cursor=pointer]
- button "F" [ref=e72] [cursor=pointer]
- button "G" [ref=e73] [cursor=pointer]
- button "H" [ref=e74] [cursor=pointer]
- button "J" [ref=e75] [cursor=pointer]
- button "K" [ref=e76] [cursor=pointer]
- button "L" [ref=e77] [cursor=pointer]
- button "Enter" [ref=e78] [cursor=pointer]
- button "Z" [ref=e79] [cursor=pointer]
- button "X" [ref=e80] [cursor=pointer]
- button "C" [ref=e81] [cursor=pointer]
- button "V" [ref=e82] [cursor=pointer]
- button "B" [ref=e83] [cursor=pointer]
- button "N" [ref=e84] [cursor=pointer]
- button "M" [ref=e85] [cursor=pointer]
- button "Delete letter" [ref=e86] [cursor=pointer]: ⌫
@@ -1,88 +0,0 @@
- generic [ref=e2]:
- banner "Game controls" [ref=e3]:
- link "Restart Fancy Wordle" [ref=e4] [cursor=pointer]:
- /url: "#"
- generic [ref=e5]: W
- generic [ref=e6]:
- strong [ref=e7]: Fancy Wordle
- text: One word every hour
- navigation "Quick actions" [ref=e8]:
- button "Toggle dark mode" [ref=e9] [cursor=pointer]:
- generic [ref=e10]: ◐
- button "Open stats and share" [ref=e11] [cursor=pointer]:
- generic [ref=e12]: ↗
- button "Open hourly leaderboard" [ref=e13] [cursor=pointer]:
- generic [ref=e14]: ♛
- button "Sign in to sync stats" [ref=e15] [cursor=pointer]: Sign in
- link "Open the original love note" [ref=e16] [cursor=pointer]:
- /url: https://www.youtube.com/watch?v=UkOKCWDJ4iA
- generic [ref=e17]: ♡
- main [ref=e18]:
- region "Guess the word in six tries." [ref=e19]:
- paragraph [ref=e20]: Hourly challenge
- heading "Guess the word in six tries." [level=1] [ref=e21]
- paragraph [ref=e22]: Play one five-letter word per hour. Valid words reveal with smooth flips, warm feedback, confetti, sound, and a definition at the end.
- region "Wordle game board" [ref=e23]:
- generic [ref=e24]:
- generic [ref=e25]: Loading word lists…
- generic [ref=e26]: 0 / 6
- generic "Guess grid" [ref=e27]:
- img "Empty letter" [ref=e28]
- img "Empty letter" [ref=e29]
- img "Empty letter" [ref=e30]
- img "Empty letter" [ref=e31]
- img "Empty letter" [ref=e32]
- img "Empty letter" [ref=e33]
- img "Empty letter" [ref=e34]
- img "Empty letter" [ref=e35]
- img "Empty letter" [ref=e36]
- img "Empty letter" [ref=e37]
- img "Empty letter" [ref=e38]
- img "Empty letter" [ref=e39]
- img "Empty letter" [ref=e40]
- img "Empty letter" [ref=e41]
- img "Empty letter" [ref=e42]
- img "Empty letter" [ref=e43]
- img "Empty letter" [ref=e44]
- img "Empty letter" [ref=e45]
- img "Empty letter" [ref=e46]
- img "Empty letter" [ref=e47]
- img "Empty letter" [ref=e48]
- img "Empty letter" [ref=e49]
- img "Empty letter" [ref=e50]
- img "Empty letter" [ref=e51]
- img "Empty letter" [ref=e52]
- img "Empty letter" [ref=e53]
- img "Empty letter" [ref=e54]
- img "Empty letter" [ref=e55]
- img "Empty letter" [ref=e56]
- img "Empty letter" [ref=e57]
- generic "Keyboard" [ref=e58]:
- button "Q" [ref=e59] [cursor=pointer]
- button "W" [ref=e60] [cursor=pointer]
- button "E" [ref=e61] [cursor=pointer]
- button "R" [ref=e62] [cursor=pointer]
- button "T" [ref=e63] [cursor=pointer]
- button "Y" [ref=e64] [cursor=pointer]
- button "U" [ref=e65] [cursor=pointer]
- button "I" [ref=e66] [cursor=pointer]
- button "O" [ref=e67] [cursor=pointer]
- button "P" [ref=e68] [cursor=pointer]
- button "A" [ref=e69] [cursor=pointer]
- button "S" [ref=e70] [cursor=pointer]
- button "D" [ref=e71] [cursor=pointer]
- button "F" [ref=e72] [cursor=pointer]
- button "G" [ref=e73] [cursor=pointer]
- button "H" [ref=e74] [cursor=pointer]
- button "J" [ref=e75] [cursor=pointer]
- button "K" [ref=e76] [cursor=pointer]
- button "L" [ref=e77] [cursor=pointer]
- button "Enter" [ref=e78] [cursor=pointer]
- button "Z" [ref=e79] [cursor=pointer]
- button "X" [ref=e80] [cursor=pointer]
- button "C" [ref=e81] [cursor=pointer]
- button "V" [ref=e82] [cursor=pointer]
- button "B" [ref=e83] [cursor=pointer]
- button "N" [ref=e84] [cursor=pointer]
- button "M" [ref=e85] [cursor=pointer]
- button "Delete letter" [ref=e86] [cursor=pointer]: ⌫
@@ -1,88 +0,0 @@
- generic [ref=e2]:
- banner "Game controls" [ref=e3]:
- link "Restart Fancy Wordle" [ref=e4] [cursor=pointer]:
- /url: "#"
- generic [ref=e5]: W
- generic [ref=e6]:
- strong [ref=e7]: Fancy Wordle
- text: One word every hour
- navigation "Quick actions" [ref=e8]:
- button "Switch to light mode" [active] [ref=e87] [cursor=pointer]:
- generic [ref=e10]: ◐
- button "Open stats and share" [ref=e11] [cursor=pointer]:
- generic [ref=e12]: ↗
- button "Open hourly leaderboard" [ref=e13] [cursor=pointer]:
- generic [ref=e14]: ♛
- button "Sign in to sync stats" [ref=e15] [cursor=pointer]: Sign in
- link "Open the original love note" [ref=e16] [cursor=pointer]:
- /url: https://www.youtube.com/watch?v=UkOKCWDJ4iA
- generic [ref=e17]: ♡
- main [ref=e18]:
- region "Guess the word in six tries." [ref=e19]:
- paragraph [ref=e20]: Hourly challenge
- heading "Guess the word in six tries." [level=1] [ref=e21]
- paragraph [ref=e22]: Play one five-letter word per hour. Valid words reveal with smooth flips, warm feedback, confetti, sound, and a definition at the end.
- region "Wordle game board" [ref=e23]:
- generic [ref=e24]:
- generic [ref=e25]: Hourly word resumed
- generic [ref=e26]: 0 / 6
- generic "Guess grid" [ref=e27]:
- img "Empty letter" [ref=e28]
- img "Empty letter" [ref=e29]
- img "Empty letter" [ref=e30]
- img "Empty letter" [ref=e31]
- img "Empty letter" [ref=e32]
- img "Empty letter" [ref=e33]
- img "Empty letter" [ref=e34]
- img "Empty letter" [ref=e35]
- img "Empty letter" [ref=e36]
- img "Empty letter" [ref=e37]
- img "Empty letter" [ref=e38]
- img "Empty letter" [ref=e39]
- img "Empty letter" [ref=e40]
- img "Empty letter" [ref=e41]
- img "Empty letter" [ref=e42]
- img "Empty letter" [ref=e43]
- img "Empty letter" [ref=e44]
- img "Empty letter" [ref=e45]
- img "Empty letter" [ref=e46]
- img "Empty letter" [ref=e47]
- img "Empty letter" [ref=e48]
- img "Empty letter" [ref=e49]
- img "Empty letter" [ref=e50]
- img "Empty letter" [ref=e51]
- img "Empty letter" [ref=e52]
- img "Empty letter" [ref=e53]
- img "Empty letter" [ref=e54]
- img "Empty letter" [ref=e55]
- img "Empty letter" [ref=e56]
- img "Empty letter" [ref=e57]
- generic "Keyboard" [ref=e58]:
- button "Q" [ref=e59] [cursor=pointer]
- button "W" [ref=e60] [cursor=pointer]
- button "E" [ref=e61] [cursor=pointer]
- button "R" [ref=e62] [cursor=pointer]
- button "T" [ref=e63] [cursor=pointer]
- button "Y" [ref=e64] [cursor=pointer]
- button "U" [ref=e65] [cursor=pointer]
- button "I" [ref=e66] [cursor=pointer]
- button "O" [ref=e67] [cursor=pointer]
- button "P" [ref=e68] [cursor=pointer]
- button "A" [ref=e69] [cursor=pointer]
- button "S" [ref=e70] [cursor=pointer]
- button "D" [ref=e71] [cursor=pointer]
- button "F" [ref=e72] [cursor=pointer]
- button "G" [ref=e73] [cursor=pointer]
- button "H" [ref=e74] [cursor=pointer]
- button "J" [ref=e75] [cursor=pointer]
- button "K" [ref=e76] [cursor=pointer]
- button "L" [ref=e77] [cursor=pointer]
- button "Enter" [ref=e78] [cursor=pointer]
- button "Z" [ref=e79] [cursor=pointer]
- button "X" [ref=e80] [cursor=pointer]
- button "C" [ref=e81] [cursor=pointer]
- button "V" [ref=e82] [cursor=pointer]
- button "B" [ref=e83] [cursor=pointer]
- button "N" [ref=e84] [cursor=pointer]
- button "M" [ref=e85] [cursor=pointer]
- button "Delete letter" [ref=e86] [cursor=pointer]: ⌫
@@ -1,88 +0,0 @@
- generic [ref=e2]:
- banner "Game controls" [ref=e3]:
- link "Restart Fancy Wordle" [ref=e4] [cursor=pointer]:
- /url: "#"
- generic [ref=e5]: W
- generic [ref=e6]:
- strong [ref=e7]: Fancy Wordle
- text: One word every hour
- navigation "Quick actions" [ref=e8]:
- button "Switch to light mode" [ref=e9] [cursor=pointer]:
- generic [ref=e10]: ◐
- button "Open stats and share" [ref=e11] [cursor=pointer]:
- generic [ref=e12]: ↗
- button "Open hourly leaderboard" [ref=e13] [cursor=pointer]:
- generic [ref=e14]: ♛
- button "Sign in to sync stats" [ref=e15] [cursor=pointer]: Sign in
- link "Open the original love note" [ref=e16] [cursor=pointer]:
- /url: https://www.youtube.com/watch?v=UkOKCWDJ4iA
- generic [ref=e17]: ♡
- main [ref=e18]:
- region "Guess the word in six tries." [ref=e19]:
- paragraph [ref=e20]: Hourly challenge
- heading "Guess the word in six tries." [level=1] [ref=e21]
- paragraph [ref=e22]: Play one five-letter word per hour. Valid words reveal with smooth flips, warm feedback, confetti, sound, and a definition at the end.
- region "Wordle game board" [ref=e23]:
- generic [ref=e24]:
- generic [ref=e25]: Loading word lists…
- generic [ref=e26]: 0 / 6
- generic "Guess grid" [ref=e27]:
- img "Empty letter" [ref=e28]
- img "Empty letter" [ref=e29]
- img "Empty letter" [ref=e30]
- img "Empty letter" [ref=e31]
- img "Empty letter" [ref=e32]
- img "Empty letter" [ref=e33]
- img "Empty letter" [ref=e34]
- img "Empty letter" [ref=e35]
- img "Empty letter" [ref=e36]
- img "Empty letter" [ref=e37]
- img "Empty letter" [ref=e38]
- img "Empty letter" [ref=e39]
- img "Empty letter" [ref=e40]
- img "Empty letter" [ref=e41]
- img "Empty letter" [ref=e42]
- img "Empty letter" [ref=e43]
- img "Empty letter" [ref=e44]
- img "Empty letter" [ref=e45]
- img "Empty letter" [ref=e46]
- img "Empty letter" [ref=e47]
- img "Empty letter" [ref=e48]
- img "Empty letter" [ref=e49]
- img "Empty letter" [ref=e50]
- img "Empty letter" [ref=e51]
- img "Empty letter" [ref=e52]
- img "Empty letter" [ref=e53]
- img "Empty letter" [ref=e54]
- img "Empty letter" [ref=e55]
- img "Empty letter" [ref=e56]
- img "Empty letter" [ref=e57]
- generic "Keyboard" [ref=e58]:
- button "Q" [ref=e59] [cursor=pointer]
- button "W" [ref=e60] [cursor=pointer]
- button "E" [ref=e61] [cursor=pointer]
- button "R" [ref=e62] [cursor=pointer]
- button "T" [ref=e63] [cursor=pointer]
- button "Y" [ref=e64] [cursor=pointer]
- button "U" [ref=e65] [cursor=pointer]
- button "I" [ref=e66] [cursor=pointer]
- button "O" [ref=e67] [cursor=pointer]
- button "P" [ref=e68] [cursor=pointer]
- button "A" [ref=e69] [cursor=pointer]
- button "S" [ref=e70] [cursor=pointer]
- button "D" [ref=e71] [cursor=pointer]
- button "F" [ref=e72] [cursor=pointer]
- button "G" [ref=e73] [cursor=pointer]
- button "H" [ref=e74] [cursor=pointer]
- button "J" [ref=e75] [cursor=pointer]
- button "K" [ref=e76] [cursor=pointer]
- button "L" [ref=e77] [cursor=pointer]
- button "Enter" [ref=e78] [cursor=pointer]
- button "Z" [ref=e79] [cursor=pointer]
- button "X" [ref=e80] [cursor=pointer]
- button "C" [ref=e81] [cursor=pointer]
- button "V" [ref=e82] [cursor=pointer]
- button "B" [ref=e83] [cursor=pointer]
- button "N" [ref=e84] [cursor=pointer]
- button "M" [ref=e85] [cursor=pointer]
- button "Delete letter" [ref=e86] [cursor=pointer]: ⌫
@@ -1,86 +0,0 @@
- generic [ref=e2]:
- banner "Game controls" [ref=e3]:
- link "Restart Fancy Wordle" [ref=e4] [cursor=pointer]:
- /url: "#"
- generic [ref=e5]: W
- strong [ref=e7]: Fancy Wordle
- navigation "Quick actions" [ref=e8]:
- button "Switch to light mode" [ref=e9] [cursor=pointer]:
- generic [ref=e10]: ◐
- button "Open stats and share" [ref=e11] [cursor=pointer]:
- generic [ref=e12]: ↗
- button "Open hourly leaderboard" [ref=e13] [cursor=pointer]:
- generic [ref=e14]: ♛
- button "Sign in to sync stats" [ref=e15] [cursor=pointer]: Sign in
- link "Open the original love note" [ref=e16] [cursor=pointer]:
- /url: https://www.youtube.com/watch?v=UkOKCWDJ4iA
- generic [ref=e17]: ♡
- main [ref=e18]:
- region "Guess the word in six tries." [ref=e19]:
- paragraph [ref=e20]: Hourly challenge
- heading "Guess the word in six tries." [level=1] [ref=e21]
- paragraph [ref=e22]: Play one five-letter word per hour. Valid words reveal with smooth flips, warm feedback, confetti, sound, and a definition at the end.
- region "Wordle game board" [ref=e23]:
- generic [ref=e24]:
- generic [ref=e25]: Hourly word ready
- generic [ref=e26]: 0 / 6
- generic "Guess grid" [ref=e27]:
- img "Empty letter" [ref=e28]
- img "Empty letter" [ref=e29]
- img "Empty letter" [ref=e30]
- img "Empty letter" [ref=e31]
- img "Empty letter" [ref=e32]
- img "Empty letter" [ref=e33]
- img "Empty letter" [ref=e34]
- img "Empty letter" [ref=e35]
- img "Empty letter" [ref=e36]
- img "Empty letter" [ref=e37]
- img "Empty letter" [ref=e38]
- img "Empty letter" [ref=e39]
- img "Empty letter" [ref=e40]
- img "Empty letter" [ref=e41]
- img "Empty letter" [ref=e42]
- img "Empty letter" [ref=e43]
- img "Empty letter" [ref=e44]
- img "Empty letter" [ref=e45]
- img "Empty letter" [ref=e46]
- img "Empty letter" [ref=e47]
- img "Empty letter" [ref=e48]
- img "Empty letter" [ref=e49]
- img "Empty letter" [ref=e50]
- img "Empty letter" [ref=e51]
- img "Empty letter" [ref=e52]
- img "Empty letter" [ref=e53]
- img "Empty letter" [ref=e54]
- img "Empty letter" [ref=e55]
- img "Empty letter" [ref=e56]
- img "Empty letter" [ref=e57]
- generic "Keyboard" [ref=e58]:
- button "Q" [ref=e59] [cursor=pointer]
- button "W" [ref=e60] [cursor=pointer]
- button "E" [ref=e61] [cursor=pointer]
- button "R" [ref=e62] [cursor=pointer]
- button "T" [ref=e63] [cursor=pointer]
- button "Y" [ref=e64] [cursor=pointer]
- button "U" [ref=e65] [cursor=pointer]
- button "I" [ref=e66] [cursor=pointer]
- button "O" [ref=e67] [cursor=pointer]
- button "P" [ref=e68] [cursor=pointer]
- button "A" [ref=e69] [cursor=pointer]
- button "S" [ref=e70] [cursor=pointer]
- button "D" [ref=e71] [cursor=pointer]
- button "F" [ref=e72] [cursor=pointer]
- button "G" [ref=e73] [cursor=pointer]
- button "H" [ref=e74] [cursor=pointer]
- button "J" [ref=e75] [cursor=pointer]
- button "K" [ref=e76] [cursor=pointer]
- button "L" [ref=e77] [cursor=pointer]
- button "Enter" [ref=e78] [cursor=pointer]
- button "Z" [ref=e79] [cursor=pointer]
- button "X" [ref=e80] [cursor=pointer]
- button "C" [ref=e81] [cursor=pointer]
- button "V" [ref=e82] [cursor=pointer]
- button "B" [ref=e83] [cursor=pointer]
- button "N" [ref=e84] [cursor=pointer]
- button "M" [ref=e85] [cursor=pointer]
- button "Delete letter" [ref=e86] [cursor=pointer]: ⌫
@@ -1,88 +0,0 @@
- generic [ref=e2]:
- banner "Game controls" [ref=e3]:
- link "Restart Fancy Wordle" [ref=e4] [cursor=pointer]:
- /url: "#"
- generic [ref=e5]: W
- generic [ref=e6]:
- strong [ref=e7]: Fancy Wordle
- text: One word every hour
- navigation "Quick actions" [ref=e8]:
- button "Switch to light mode" [ref=e9] [cursor=pointer]:
- generic [ref=e10]: ◐
- button "Open stats and share" [ref=e11] [cursor=pointer]:
- generic [ref=e12]: ↗
- button "Open hourly leaderboard" [ref=e13] [cursor=pointer]:
- generic [ref=e14]: ♛
- button "Sign in to sync stats" [ref=e15] [cursor=pointer]: Sign in
- link "Open the original love note" [ref=e16] [cursor=pointer]:
- /url: https://www.youtube.com/watch?v=UkOKCWDJ4iA
- generic [ref=e17]: ♡
- main [ref=e18]:
- region "Guess the word in six tries." [ref=e19]:
- paragraph [ref=e20]: Hourly challenge
- heading "Guess the word in six tries." [level=1] [ref=e21]
- paragraph [ref=e22]: Play one five-letter word per hour. Valid words reveal with smooth flips, warm feedback, confetti, sound, and a definition at the end.
- region "Wordle game board" [ref=e23]:
- generic [ref=e24]:
- generic [ref=e25]: Loading word lists…
- generic [ref=e26]: 0 / 6
- generic "Guess grid" [ref=e27]:
- img "Empty letter" [ref=e28]
- img "Empty letter" [ref=e29]
- img "Empty letter" [ref=e30]
- img "Empty letter" [ref=e31]
- img "Empty letter" [ref=e32]
- img "Empty letter" [ref=e33]
- img "Empty letter" [ref=e34]
- img "Empty letter" [ref=e35]
- img "Empty letter" [ref=e36]
- img "Empty letter" [ref=e37]
- img "Empty letter" [ref=e38]
- img "Empty letter" [ref=e39]
- img "Empty letter" [ref=e40]
- img "Empty letter" [ref=e41]
- img "Empty letter" [ref=e42]
- img "Empty letter" [ref=e43]
- img "Empty letter" [ref=e44]
- img "Empty letter" [ref=e45]
- img "Empty letter" [ref=e46]
- img "Empty letter" [ref=e47]
- img "Empty letter" [ref=e48]
- img "Empty letter" [ref=e49]
- img "Empty letter" [ref=e50]
- img "Empty letter" [ref=e51]
- img "Empty letter" [ref=e52]
- img "Empty letter" [ref=e53]
- img "Empty letter" [ref=e54]
- img "Empty letter" [ref=e55]
- img "Empty letter" [ref=e56]
- img "Empty letter" [ref=e57]
- generic "Keyboard" [ref=e58]:
- button "Q" [ref=e59] [cursor=pointer]
- button "W" [ref=e60] [cursor=pointer]
- button "E" [ref=e61] [cursor=pointer]
- button "R" [ref=e62] [cursor=pointer]
- button "T" [ref=e63] [cursor=pointer]
- button "Y" [ref=e64] [cursor=pointer]
- button "U" [ref=e65] [cursor=pointer]
- button "I" [ref=e66] [cursor=pointer]
- button "O" [ref=e67] [cursor=pointer]
- button "P" [ref=e68] [cursor=pointer]
- button "A" [ref=e69] [cursor=pointer]
- button "S" [ref=e70] [cursor=pointer]
- button "D" [ref=e71] [cursor=pointer]
- button "F" [ref=e72] [cursor=pointer]
- button "G" [ref=e73] [cursor=pointer]
- button "H" [ref=e74] [cursor=pointer]
- button "J" [ref=e75] [cursor=pointer]
- button "K" [ref=e76] [cursor=pointer]
- button "L" [ref=e77] [cursor=pointer]
- button "Enter" [ref=e78] [cursor=pointer]
- button "Z" [ref=e79] [cursor=pointer]
- button "X" [ref=e80] [cursor=pointer]
- button "C" [ref=e81] [cursor=pointer]
- button "V" [ref=e82] [cursor=pointer]
- button "B" [ref=e83] [cursor=pointer]
- button "N" [ref=e84] [cursor=pointer]
- button "M" [ref=e85] [cursor=pointer]
- button "Delete letter" [ref=e86] [cursor=pointer]: ⌫
-314
View File
@@ -1,314 +0,0 @@
*, *::after, *::before{
box-sizing: border-box;
}
body{
background-color: hsl(0, 67%, 96%);
display: flex;
text-align: center;
flex-direction: column;
min-height: 100vh;
margin: 0;
padding: 1em;
font-size: clamp(.5rem, 2.5vmin, 1.5rem);
}
.keyboard {
display: grid;
grid-template-columns: repeat(20, minmax(auto, 1.50em));
grid-auto-rows: 4em;
gap: .25em;
justify-content: center;
}
.key{
font-size: inherit;
grid-column: span 2;
border: none;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
background-color: hsl(
var(--hue, 200),
var(--saturation, 1%),
calc(var(--lightness-offset, 0%) + var(--lightness, 51%))
);
color: rgb(255, 255, 255);
fill: white;
text-transform: uppercase;
border-radius: .25em;
cursor: pointer;
user-select: none;
}
.key.large{
grid-column: span 3;
}
.key > svg {
width: 1.70em;
height: 1.70em;
}
.key:hover, .key:focus{
--lightness-offset: 10%;
}
.key.wrong {
--lightness: 23%;
}
.key.wrong-position{
--hue: 49;
--saturation: 51%;
--lightness: 47%;
}
.key.correct{
--hue: 115;
--saturation: 29%;
--lightness: 43%;
}
.guess-grid{
display: grid;
justify-content: center;
align-content: center;
grid-template-columns: repeat(5, 4em);
grid-template-rows: repeat(6, 4em);
gap: .25em;
margin-bottom: 1em;
}
.tile{
font-size: 2em;
color: rgb(158, 155, 155);
border: .05em solid hsl(240, 3%, 14%);
text-transform: uppercase;
font-weight: bold;
display: flex;
justify-content: center;
align-items: center;
user-select: none;
transition: transform 250ms linear;
transition: transform 250ms linear;
}
.tile[data-state="active"] {
border-color: hsl(240, 1%, 18%);
}
.tile[data-state="wrong"] {
border: none;
background-color: hsl(240, 12%, 24%);
color: white;
}
.tile[data-state="wrong-position"] {
border: none;
background-color: hsl(49, 51%, 47%);
color: white;
}
.tile[data-state="correct"] {
border: none;
background-color: hsl(115, 31%, 48%);
color: white;
}
.tile.shake{
animation:shake 250ms ease-in-out;
}
.tile.dance {
animation: dance 500ms ease-in-out;
}
.tile.flip {
transform: rotateX(90deg);
}
@keyframes shake {
10% {
transform: translateX(-5%);
}
30% {
transform: translateX(5%);
}
50% {
transform: translateX(-7.5%);
}
70% {
transform: translateX(7.5%);
}
90% {
transform: translateX(-5%);
}
100% {
transform: translateX(0);
}
}
@keyframes dance {
20% {
transform: translateY(-50%);
}
40% {
transform: translateY(5%);
}
60% {
transform: translateY(-25%);
}
80% {
transform: translateY(2.5%);
}
90% {
transform: translateY(-5%);
}
100% {
transform: translateY(0);
}
}
.alert-container{
position: fixed;
top: 17vh;
left: 50vw;
transform: translateX(-50%);
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
}
.alert{
pointer-events: none;
background-color: hsl(204, 7%, 85%);
padding: .55em;
border-radius: .25em;
opacity: 1;
transition: opacity 500ms ease-in-out;
margin-bottom: .5em;
}
.alert:last-child{
margin-bottom: 0;
}
.alert.hide{
opacity: 0;
}
.img-banner{
width: auto ;
max-width: 50% ;
height: auto ;
}
.theme-change{
position: absolute;
top: 2.5rem;
display: flex;
color: rgb(202, 181, 181);
font-size: 1.2rem;
cursor: pointer;
}
.theme-change:hover{
color: rgb(150, 141, 141)
}
body.dark-theme{
background-color: hsl(0, 0%, 8%);
font:white;
display: flex;
text-align: center;
flex-direction: column;
min-height: 100vh;
margin: 0;
padding: 1em;
font-size: clamp(.5rem, 2.5vmin, 1.5rem);
}
.share-stats{
position: absolute;
top: 4.5rem;
display: flex;
color: rgb(202, 181, 181);
font-size: 1.2rem;
cursor: pointer;
}
.share-stats:hover{
color: rgb(150, 141, 141)
}
.setting-page{
position: absolute;
top: 6.5rem;
display: flex;
color: rgb(202, 181, 181);
font-size: 1.2rem;
cursor: pointer;
}
.setting-page:hover{
color: rgb(150, 141, 141)
}
* Definition Alert Styles */
.definition-alert {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 20px;
border-radius: 12px;
max-width: 400px;
margin: 0 auto 10px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
border: 1px solid rgba(255, 255, 255, 0.2);
backdrop-filter: blur(10px);
cursor: pointer;
transition: all 0.3s ease;
text-align: left;
line-height: 1.6;
font-size: 14px;
}
.definition-alert:hover {
transform: translateY(-2px);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4);
}
.win-definition {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
border-color: rgba(79, 172, 254, 0.5);
}
.lose-definition {
background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
border-color: rgba(250, 112, 154, 0.5);
}
.definition-alert strong {
font-weight: 700;
font-size: 16px;
display: block;
margin-bottom: 8px;
}
.definition-alert::before {
content: "💡 Click to dismiss";
position: absolute;
top: 5px;
right: 10px;
font-size: 10px;
opacity: 0.7;
}
/* Dark theme adjustments */
.dark-theme .definition-alert {
border-color: rgba(255, 255, 255, 0.1);
}
/* Mobile responsiveness */
@media (max-width: 380px) {
.definition-alert {
max-width: 90%;
font-size: 13px;
padding: 15px;
}
}
-1
View File
@@ -2,7 +2,6 @@ FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
COPY CSS /usr/share/nginx/html/CSS
COPY img /usr/share/nginx/html/img
COPY Celebration.mp3 dictionary.json script.js supabase-config.js targetWords.json word-data.js /usr/share/nginx/html/
EXPOSE 80
+6 -2
View File
@@ -8,10 +8,14 @@ Implemented:
- Preserved dark mode, keyboard input, word-list fetches, dictionary validation, win sound, confetti, definition lookup, and the original love-link shortcut.
- Added a working stats/share dialog using localStorage.
- Improved accessibility with semantic buttons, labels, live alerts, visible focus states, and 44px touch targets.
- One shared word per UTC hour, enforced by Supabase with a browser-only fallback.
- Email/password accounts with synced stats and an hourly, daily, and all-time leaderboard.
- Animated intro with a skip button that plays once per tab.
- Reduced-motion preference for flip, dance, and intro animations.
- Definition lookup with a timeout and a second provider.
- Up to 3 saved starter words per account that fill the current row with one tap.
Good next features:
- Hard mode that forces revealed hints into later guesses.
- Daily challenge mode alongside the current unlimited mode.
- Reduced-motion preference for flip, dance, and confetti animations.
- Offline definition fallback for the target word list.
- Importable custom word packs for classroom or party play.
-160
View File
@@ -1,160 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#f7efe6">
<title>Fancy Wordle</title>
<link rel="stylesheet" href="CSS/styles.css?v=9">
<script src="https://cdn.jsdelivr.net/npm/@tsparticles/confetti@3.0.3/tsparticles.confetti.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script>
<script src="word-data.js?v=5" defer></script>
<script src="supabase-config.js?v=1" defer></script>
<script src="script.js?v=11" defer></script>
</head>
<body class="intro-active dark-theme">
<section class="intro-overlay" id="intro-overlay" aria-label="Animated Wordle intro" role="dialog" aria-modal="true">
<button class="intro-skip" type="button" id="intro-skip" aria-label="Skip intro">Skip</button>
<div class="intro-stage" aria-hidden="true">
<div class="intro-scanline"></div>
<div class="intro-tiles" id="intro-tiles">
<div class="intro-tile" data-status="wrong"><span class="intro-letter">Q</span></div>
<div class="intro-tile" data-status="wrong"><span class="intro-letter">I</span></div>
<div class="intro-tile" data-status="wrong"><span class="intro-letter">N</span></div>
<div class="intro-tile" data-status="wrong"><span class="intro-letter">Z</span></div>
<div class="intro-tile" data-status="wrong"><span class="intro-letter">A</span></div>
<div class="intro-tile" data-status="wrong"><span class="intro-letter">T</span></div>
</div>
</div>
<div class="intro-caption">six letters flip into one answer</div>
</section>
<div class="app-shell">
<header class="topbar" aria-label="Game controls">
<a class="brand" href="#" aria-label="Restart Fancy Wordle">
<span class="brand-mark">W</span>
<span>
<strong>Fancy Wordle</strong>
<small>One word every hour</small>
</span>
</a>
<nav class="actions" aria-label="Quick actions">
<button class="icon-button" type="button" id="theme-button" aria-label="Toggle dark mode" title="Toggle theme">
<span aria-hidden="true">◐</span>
</button>
<button class="icon-button" type="button" id="Stats-button" aria-label="Open stats and share" title="Stats and share">
<span aria-hidden="true">↗</span>
</button>
<button class="icon-button" type="button" id="leaderboard-button" aria-label="Open hourly leaderboard" title="Hourly leaderboard">
<span aria-hidden="true">♛</span>
</button>
<button class="auth-button" type="button" id="auth-button" aria-label="Sign in to sync stats">Sign in</button>
<a class="icon-button" href="https://www.youtube.com/watch?v=UkOKCWDJ4iA" target="_blank" rel="noopener noreferrer" aria-label="Open the original love note" title="Original love note">
<span aria-hidden="true">♡</span>
</a>
</nav>
</header>
<main class="game-card">
<section class="hero-panel" aria-labelledby="game-title">
<p class="eyebrow">Hourly challenge</p>
<h1 id="game-title">Guess the word in six tries.</h1>
<p class="deck">Play one five-letter word per hour. Valid words reveal with smooth flips, warm feedback, confetti, sound, and a definition at the end.</p>
</section>
<section class="board-panel" aria-label="Wordle game board">
<div class="status-row">
<span id="round-status">Loading word lists…</span>
<span class="pill" id="tries-status">0 / 6</span>
</div>
<div class="alert-container" data-alert-container aria-live="polite" aria-atomic="true"></div>
<div data-guess-grid class="guess-grid" aria-label="Guess grid"></div>
<div data-keyboard class="keyboard" aria-label="Keyboard"></div>
</section>
</main>
</div>
<dialog class="stats-modal" id="stats-modal" aria-labelledby="stats-title">
<form method="dialog" class="stats-card">
<div class="modal-head">
<div>
<p class="eyebrow">Progress</p>
<h2 id="stats-title">Game stats</h2>
</div>
<button class="icon-button close-button" type="submit" aria-label="Close stats">×</button>
</div>
<div class="stats-grid" id="stats-grid"></div>
<div class="stats-note" id="stats-note"></div>
<div class="guess-bars" id="guess-bars" aria-label="Guess distribution"></div>
<div class="definition-panel" id="stats-definition-panel">
<h3>Word reveal</h3>
<div class="stats-definition" id="stats-definition"></div>
</div>
<menu class="modal-actions">
<button type="button" class="button secondary" id="reset-stats">Reset stats</button>
<button type="button" class="button primary" id="share-results">Share result</button>
</menu>
</form>
</dialog>
<dialog class="stats-modal" id="leaderboard-modal" aria-labelledby="leaderboard-title">
<form method="dialog" class="stats-card leaderboard-card">
<div class="modal-head">
<div>
<p class="eyebrow">This hour</p>
<h2 id="leaderboard-title">Leaderboard</h2>
</div>
<button class="icon-button close-button" type="submit" aria-label="Close leaderboard">×</button>
</div>
<div class="leaderboard-tabs" role="tablist" aria-label="Leaderboard scope">
<button type="button" class="leaderboard-tab active" data-leaderboard-scope="hour">This Hour</button>
<button type="button" class="leaderboard-tab" data-leaderboard-scope="today">Today</button>
<button type="button" class="leaderboard-tab" data-leaderboard-scope="all">All Time</button>
</div>
<div class="leaderboard-result" id="leaderboard-result" hidden></div>
<p class="leaderboard-countdown" id="leaderboard-countdown">Next word unlocks soon.</p>
<div class="leaderboard-list" id="leaderboard-list" aria-live="polite"></div>
</form>
</dialog>
<dialog class="stats-modal auth-modal" id="auth-modal" aria-labelledby="auth-title">
<form method="dialog" class="stats-card auth-card">
<div class="modal-head">
<div>
<p class="eyebrow">Account</p>
<h2 id="auth-title">Sign in</h2>
</div>
<button class="icon-button close-button" type="submit" aria-label="Close account">×</button>
</div>
<p class="auth-status" id="auth-status">Sign in with your email and password. If we cannot find your account, you can create one here.</p>
<div class="account-summary" id="account-summary" hidden></div>
<div id="auth-form" class="auth-form">
<label for="auth-email">Email address</label>
<input type="email" id="auth-email" autocomplete="email" placeholder="you@example.com">
<label for="auth-password">Password</label>
<input type="password" id="auth-password" autocomplete="current-password" placeholder="At least 6 characters" minlength="6">
<div class="auth-create-fields" id="auth-create-fields" hidden>
<label for="auth-username">Username</label>
<input type="text" id="auth-username" autocomplete="username" placeholder="wordsmith" maxlength="24">
</div>
<div class="auth-button-row">
<button type="button" class="button primary" id="auth-sign-in">Sign in</button>
<button type="button" class="button secondary" id="auth-sign-up" hidden>Create account</button>
</div>
<button type="button" class="link-button" id="auth-forgot-password">Forgot password?</button>
<div class="auth-reset-fields" id="auth-reset-fields" hidden>
<label for="auth-new-password">New password</label>
<input type="password" id="auth-new-password" autocomplete="new-password" placeholder="New password" minlength="6">
<button type="button" class="button secondary full-width" id="auth-update-password">Update password</button>
</div>
</div>
<menu class="modal-actions auth-actions">
<button type="button" class="button secondary" id="auth-guest">Continue as guest</button>
<button type="button" class="button secondary" id="auth-sign-out" hidden>Sign out</button>
</menu>
</form>
</dialog>
</body>
</html>
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

-532
View File
@@ -1,532 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>WORDLE Intro</title>
<style>
:root {
--bg: #111111;
--surface: #ffffff;
--fg: #fafafa;
--muted: #6b6b6b;
--border: #e5e5e5;
--accent: #2f6feb;
--tile-empty: #3a3a3c;
--tile-wrong: #787c7e;
--tile-misplaced: #c9b458;
--tile-correct: #6aaa64;
--font-display: "Inter", -apple-system, system-ui, sans-serif;
--font-body: "Inter", -apple-system, system-ui, sans-serif;
--font-mono: ui-monospace, "JetBrains Mono", monospace;
}
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
min-height: 100%;
background: var(--bg);
color: var(--fg);
font-family: var(--font-body);
overflow: hidden;
}
body {
min-height: 100vh;
display: grid;
place-items: center;
}
.stage {
position: relative;
inline-size: 100vw;
block-size: 100vh;
min-block-size: 520px;
display: grid;
place-items: center;
background: linear-gradient(
180deg,
#181818 0%,
#111111 58%,
#080808 100%
);
perspective: 1200px;
isolation: isolate;
}
.stage::before,
.stage::after {
content: "";
position: absolute;
inset-inline: 0;
block-size: 20vh;
z-index: 4;
pointer-events: none;
}
.stage::before {
inset-block-start: 0;
background: linear-gradient(
180deg,
rgba(17, 17, 17, 0.85),
transparent
);
}
.stage::after {
inset-block-end: 0;
background: linear-gradient(
0deg,
rgba(17, 17, 17, 0.88),
transparent
);
}
.intro {
position: relative;
inline-size: min(1120px, calc(100vw - 32px));
block-size: min(640px, calc(100vh - 32px));
display: grid;
place-items: center;
transform-style: preserve-3d;
}
.scanline {
position: absolute;
inset-inline: 10%;
inset-block-start: 50%;
block-size: 1px;
background: linear-gradient(
90deg,
transparent,
rgba(250, 250, 250, 0.36),
transparent
);
transform: translateY(-50%);
opacity: 0;
animation: scan 4.8s ease forwards;
z-index: 1;
}
.tiles {
--tile-size: clamp(46px, 10vw, 128px);
--tile-gap: clamp(6px, 1.4vw, 16px);
position: relative;
display: grid;
grid-template-columns: repeat(6, var(--tile-size));
gap: var(--tile-gap);
transform-style: preserve-3d;
transform-origin: 50% 50%;
transition:
gap 420ms cubic-bezier(0.2, 0.7, 0.15, 1),
transform 520ms cubic-bezier(0.2, 0.7, 0.15, 1);
z-index: 2;
}
.tile {
position: relative;
inline-size: var(--tile-size);
block-size: var(--tile-size);
transform-style: preserve-3d;
opacity: 0;
transform: translate3d(0, 34px, -180px);
animation: tileEnter 520ms cubic-bezier(0.2, 0.7, 0.15, 1)
forwards;
animation-delay: calc(var(--i) * 56ms);
}
.letter {
position: absolute;
inset: 0;
display: grid;
place-items: center;
border: 1px solid rgba(229, 229, 229, 0.18);
background: var(--tile-empty);
color: var(--fg);
font-family: var(--font-display);
font-size: clamp(28px, 6vw, 78px);
font-weight: 700;
letter-spacing: 0;
line-height: 1;
text-transform: uppercase;
transform-origin: 50% 50%;
box-shadow: inset 0 0 0 1px rgba(250, 250, 250, 0.08);
}
.tile.is-flipping .letter {
animation: splitFlap 260ms cubic-bezier(0.3, 0.7, 0.2, 1);
}
.tile[data-status="wrong"] .letter {
background: var(--tile-wrong);
}
.tile[data-status="misplaced"] .letter {
background: var(--tile-misplaced);
}
.tile[data-status="correct"] .letter {
background: var(--tile-correct);
}
.tile:nth-child(1) {
--i: 0;
}
.tile:nth-child(2) {
--i: 1;
}
.tile:nth-child(3) {
--i: 2;
}
.tile:nth-child(4) {
--i: 3;
}
.tile:nth-child(5) {
--i: 4;
}
.tile:nth-child(6) {
--i: 5;
}
.tiles.is-solved .tile {
opacity: 1;
animation: logoCascade 680ms cubic-bezier(0.18, 0.85, 0.22, 1)
calc(var(--i) * 76ms) both;
}
.tiles.is-logo {
gap: clamp(3px, 0.7vw, 8px);
transform: scale(0.88);
}
.tiles.is-logo .letter {
border-color: rgba(250, 250, 250, 0.28);
box-shadow:
inset 0 0 0 1px rgba(250, 250, 250, 0.1),
0 0 28px rgba(106, 170, 100, 0.16);
}
.caption {
position: absolute;
inset-block-end: clamp(24px, 6vh, 64px);
inset-inline: 24px;
display: flex;
justify-content: center;
color: rgba(250, 250, 250, 0.62);
font-family: var(--font-mono);
font-size: 12px;
letter-spacing: 0.08em;
text-transform: uppercase;
z-index: 5;
opacity: 0;
animation: captionCue 4.8s ease forwards;
}
.replay {
position: fixed;
inset-block-start: 16px;
inset-inline-end: 16px;
z-index: 10;
border: 1px solid rgba(229, 229, 229, 0.22);
border-radius: 8px;
padding: 10px 16px;
background: rgba(17, 17, 17, 0.74);
color: var(--fg);
font: 600 14px/1 var(--font-body);
cursor: pointer;
}
.replay:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 3px;
}
.replay:hover {
border-color: rgba(250, 250, 250, 0.5);
}
.stage.restarting * {
animation: none !important;
}
@keyframes tileEnter {
0% {
transform: translate3d(0, 34px, -180px);
filter: blur(2px);
opacity: 0;
}
100% {
transform: translate3d(0, 0, 0);
filter: blur(0);
opacity: 1;
}
}
@keyframes splitFlap {
0% {
transform: rotateX(0deg);
filter: brightness(1);
}
49% {
transform: rotateX(-88deg);
filter: brightness(0.72);
}
50% {
transform: rotateX(88deg);
filter: brightness(1.12);
}
100% {
transform: rotateX(0deg);
filter: brightness(1);
}
}
@keyframes logoCascade {
0% {
transform: translate3d(0, 0, 0) scale(1);
filter: brightness(1);
}
34% {
transform: translate3d(0, -22%, 130px) scale(1.18);
filter: brightness(1.16);
}
62% {
transform: translate3d(0, 4%, 0) scale(0.98);
filter: brightness(1.04);
}
100% {
transform: translate3d(0, 0, 0) scale(1);
filter: brightness(1);
}
}
@keyframes scan {
0%,
12% {
opacity: 0;
transform: translateY(-50%) scaleX(0.2);
}
24% {
opacity: 0.75;
}
54% {
opacity: 0.22;
transform: translateY(-50%) scaleX(1);
}
72%,
100% {
opacity: 0;
}
}
@keyframes captionCue {
0%,
18% {
opacity: 0;
transform: translateY(8px);
}
28%,
64% {
opacity: 1;
transform: translateY(0);
}
82%,
100% {
opacity: 0;
transform: translateY(-8px);
}
}
@media (max-width: 720px) {
.stage {
min-block-size: 420px;
}
.tiles {
--tile-size: min(13.5vw, 56px);
--tile-gap: 5px;
}
.caption {
font-size: 10px;
}
.replay {
padding: 9px 12px;
}
}
@media (prefers-reduced-motion: reduce) {
.tiles,
.tile,
.tile .letter,
.scanline,
.caption {
animation-duration: 1ms;
animation-delay: 0ms;
}
}
</style>
</head>
<body>
<main class="stage" aria-label="Animated Wordle intro">
<button class="replay" type="button" aria-label="Replay intro">
Replay
</button>
<div class="intro" aria-hidden="true">
<div class="scanline"></div>
<div class="tiles" id="tiles">
<div class="tile" data-final="W" data-status="wrong">
<span class="letter">Q</span>
</div>
<div class="tile" data-final="O" data-status="wrong">
<span class="letter">I</span>
</div>
<div class="tile" data-final="R" data-status="wrong">
<span class="letter">N</span>
</div>
<div class="tile" data-final="D" data-status="wrong">
<span class="letter">Z</span>
</div>
<div class="tile" data-final="L" data-status="wrong">
<span class="letter">A</span>
</div>
<div class="tile" data-final="E" data-status="wrong">
<span class="letter">T</span>
</div>
</div>
</div>
<div class="caption">six letters flip into one answer</div>
</main>
<script>
const LETTER_SETS = [
["D", "E", "S", "I", "G", "N"],
["C", "A", "M", "E", "R", "A"],
["A", "S", "P", "E", "C", "T"],
["W", "O", "R", "D", "L", "E"],
];
const STATUS_SETS = [
["wrong", "wrong", "wrong", "wrong", "wrong", "wrong"],
["wrong", "misplaced", "wrong", "misplaced", "wrong", "wrong"],
[
"misplaced",
"wrong",
"misplaced",
"wrong",
"wrong",
"misplaced",
],
[
"correct",
"correct",
"correct",
"correct",
"correct",
"correct",
],
];
const SOUND_EVENTS = [
[280, "flip-start"],
[1280, "misplaced-pass"],
[2460, "answer-lock"],
[3720, "logo-lock"],
];
const stage = document.querySelector(".stage");
const tileRow = document.querySelector(".tiles");
const tiles = Array.from(document.querySelectorAll(".tile"));
const replay = document.querySelector(".replay");
let timers = [];
function setTile(tile, letter, status) {
tile.dataset.status = status;
tile.querySelector(".letter").textContent = letter;
}
function flipTile(tile, letter, status, delay) {
timers.push(
setTimeout(() => {
tile.classList.add("is-flipping");
timers.push(
setTimeout(
() => setTile(tile, letter, status),
130,
),
);
timers.push(
setTimeout(
() => tile.classList.remove("is-flipping"),
285,
),
);
}, delay),
);
}
function setFrame(frameIndex, animate = true) {
tiles.forEach((tile, index) => {
const letter = LETTER_SETS[frameIndex][index];
const status = STATUS_SETS[frameIndex][index];
if (animate) {
flipTile(tile, letter, status, index * 58);
} else {
tile.classList.remove("is-flipping");
setTile(tile, letter, status);
}
});
if (frameIndex === LETTER_SETS.length - 1) {
timers.push(
setTimeout(
() => tileRow.classList.add("is-solved"),
420,
),
);
timers.push(
setTimeout(
() => tileRow.classList.add("is-logo"),
1180,
),
);
}
}
function dispatchSoundCue(name) {
window.dispatchEvent(
new CustomEvent("wordleIntro:soundCue", {
detail: { name },
}),
);
}
function scheduleSequence() {
timers.forEach(clearTimeout);
timers = [];
tileRow.classList.remove("is-solved", "is-logo");
setFrame(0, false);
[880, 1720, 2580].forEach((time, index) => {
timers.push(
setTimeout(() => setFrame(index + 1, true), time),
);
});
SOUND_EVENTS.forEach(([time, name]) => {
timers.push(setTimeout(() => dispatchSoundCue(name), time));
});
}
function replayIntro() {
stage.classList.add("restarting");
scheduleSequence();
window.requestAnimationFrame(() => {
window.requestAnimationFrame(() => {
stage.classList.remove("restarting");
});
});
}
replay.addEventListener("click", replayIntro);
scheduleSequence();
</script>
</body>
</html>