brainstorm.html 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Wordle Clone Brainstorm</title>
  7. <style>
  8. /* ===== RESET & BASE ===== */
  9. *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
  10. html { scroll-behavior: smooth; }
  11. body {
  12. font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
  13. background: #0b0f14;
  14. color: #e2e8f0;
  15. line-height: 1.6;
  16. overflow-x: hidden;
  17. }
  18. /* ===== CUSTOM PROPERTIES ===== */
  19. :root {
  20. --green: #6aaa64;
  21. --yellow: #c9b458;
  22. --gray: #787c7e;
  23. --darkest:#0b0f14;
  24. --card: #161b22;
  25. --card-hover: #1c2330;
  26. --text: #e2e8f0;
  27. --muted: #8b949e;
  28. --amber: #d2991d;
  29. --accent: #58a6ff;
  30. --tile-size: 52px;
  31. --gap: 6px;
  32. }
  33. /* ===== TILE UTILITY ===== */
  34. .tile {
  35. width: var(--tile-size); height: var(--tile-size);
  36. display: inline-flex; align-items: center; justify-content: center;
  37. font-weight: 800; font-size: 1.5rem; text-transform: uppercase;
  38. border-radius: 4px; transition: transform 0.3s, background 0.3s;
  39. }
  40. .tile.green { background: var(--green); color: #fff; }
  41. .tile.yellow { background: var(--yellow); color: #fff; }
  42. .tile.gray { background: var(--gray); color: #fff; }
  43. .tile.empty { background: transparent; border: 2px solid #30363d; color: var(--muted); }
  44. /* ===== HERO ===== */
  45. .hero {
  46. min-height: 100vh; display: flex; flex-direction: column;
  47. align-items: center; justify-content: center;
  48. padding: 2rem; text-align: center;
  49. position: relative;
  50. }
  51. .hero-grid { display: flex; gap: var(--gap); margin-bottom: 2rem; flex-wrap: wrap; justify-content: center; }
  52. .hero h1 { font-size: clamp(2rem, 6vw, 4rem); font-weight: 900; letter-spacing: -0.02em; margin-bottom: 0.5rem; }
  53. .hero .subtitle { color: var(--muted); font-size: 1.15rem; max-width: 520px; }
  54. .hero .meta { margin-top: 2rem; color: #484f58; font-size: 0.85rem; }
  55. .scroll-hint {
  56. position: absolute; bottom: 2rem; left: 50%; transform: translateX(-50%);
  57. animation: bob 2s ease-in-out infinite; color: var(--muted); font-size: 0.8rem;
  58. letter-spacing: 0.1em; text-transform: uppercase;
  59. }
  60. @keyframes bob { 0%,100%{opacity:0.3;transform:translateX(-50%) translateY(0)} 50%{opacity:1;transform:translateX(-50%) translateY(8px)} }
  61. /* ===== SECTION COMMON ===== */
  62. section { padding: 5rem 2rem; max-width: 1100px; margin: 0 auto; }
  63. .section-label {
  64. font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.2em;
  65. color: var(--muted); margin-bottom: 0.75rem;
  66. }
  67. .section-title { font-size: clamp(1.6rem, 4vw, 2.2rem); font-weight: 800; margin-bottom: 2.5rem; }
  68. .section-desc { color: var(--muted); max-width: 640px; margin-bottom: 2.5rem; font-size: 1.05rem; }
  69. /* ===== SCAMPER SECTION ===== */
  70. #scamper { }
  71. .scamper-grid {
  72. display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  73. gap: 1rem;
  74. }
  75. .scamper-card {
  76. background: var(--card); border-radius: 12px; padding: 1.5rem 1rem;
  77. text-align: center; cursor: pointer; transition: all 0.3s;
  78. border: 1px solid transparent; position: relative; overflow: hidden;
  79. }
  80. .scamper-card:hover { background: var(--card-hover); border-color: #30363d; transform: translateY(-4px); }
  81. .scamper-card .letter {
  82. font-size: 3rem; font-weight: 900; line-height: 1;
  83. background: linear-gradient(135deg, var(--green), var(--accent));
  84. -webkit-background-clip: text; -webkit-text-fill-color: transparent;
  85. background-clip: text;
  86. }
  87. .scamper-card .label { font-size: 0.85rem; color: var(--muted); margin-top: 0.4rem; }
  88. .scamper-card .ideas { margin-top: 0.8rem; font-size: 0.82rem; color: #c9d1d9; line-height: 1.5; display: none; }
  89. .scamper-card.expanded .ideas { display: block; }
  90. .scamper-card.expanded { border-color: #30363d; box-shadow: 0 0 30px rgba(106,170,100,0.10); }
  91. .scamper-card .divider { width: 30px; height: 2px; background: #30363d; margin: 0.7rem auto; border-radius: 1px; }
  92. /* ===== WHAT IF SECTION ===== */
  93. #whatif { position: relative; }
  94. .branch-tree { position: relative; padding-left: 2rem; }
  95. .branch-tree::before {
  96. content: ''; position: absolute; left: 0; top: 0; bottom: 0;
  97. width: 2px; background: linear-gradient(to bottom, var(--green), #30363d 60%, #30363d);
  98. border-radius: 1px;
  99. }
  100. .branch-node { position: relative; margin-bottom: 2.5rem; padding-left: 2rem; }
  101. .branch-node::before {
  102. content: ''; position: absolute; left: -2rem; top: 1.2rem;
  103. width: 2rem; height: 2px; background: #30363d;
  104. }
  105. .branch-node .q {
  106. font-weight: 700; font-size: 1.1rem; color: var(--accent);
  107. margin-bottom: 0.4rem;
  108. }
  109. .branch-node .a {
  110. color: var(--muted); font-size: 0.95rem;
  111. display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
  112. }
  113. .branch-node .a .verdict {
  114. display: inline-block; padding: 0.15rem 0.6rem; border-radius: 20px;
  115. font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  116. white-space: nowrap;
  117. }
  118. .verdict.accept { background: rgba(106,170,100,0.18); color: var(--green); }
  119. .verdict.reject { background: rgba(120,124,126,0.18); color: var(--gray); }
  120. .verdict.later { background: rgba(201,180,88,0.18); color: var(--yellow); }
  121. /* ===== WORST POSSIBLE IDEA SECTION ===== */
  122. #worstidea {
  123. background: #f0f0f0; color: #1a1a2e; border-radius: 20px;
  124. position: relative; overflow: hidden;
  125. }
  126. #worstidea .section-label { color: #6b7280; }
  127. #worstidea .section-title { color: #1a1a2e; }
  128. #worstidea .section-desc { color: #4b5563; }
  129. .glitch-container { position: relative; }
  130. .worst-idea-card {
  131. background: #fff; border-radius: 12px; padding: 2rem;
  132. box-shadow: 0 4px 24px rgba(0,0,0,0.08);
  133. position: relative;
  134. }
  135. .worst-idea-card .bad-idea {
  136. font-size: 1.4rem; font-weight: 800; color: #dc2626;
  137. text-decoration: line-through; text-decoration-color: #fca5a5;
  138. margin-bottom: 0.5rem;
  139. }
  140. .worst-idea-card .realization {
  141. font-size: 1.05rem; color: #059669; font-weight: 600; margin-top: 1.5rem;
  142. padding-top: 1.5rem; border-top: 1px solid #e5e7eb;
  143. }
  144. .worst-idea-card .realization::before { content: '→ '; color: var(--green); }
  145. .glitch-ghost {
  146. position: absolute; top: 0; left: 0; right: 0; pointer-events: none;
  147. color: rgba(220,38,38,0.06); font-size: 6rem; font-weight: 900;
  148. text-align: center; line-height: 1; user-select: none;
  149. transform: translateY(-20%);
  150. }
  151. /* ===== KILL THE CROWN JEWEL SECTION ===== */
  152. #crownjewel { text-align: center; }
  153. .crown-tiles { display: flex; gap: var(--gap); justify-content: center; margin: 2rem 0; flex-wrap: wrap; }
  154. .cj-tile {
  155. width: 64px; height: 64px; border-radius: 8px;
  156. display: inline-flex; align-items: center; justify-content: center;
  157. font-weight: 900; font-size: 1.6rem; color: #fff;
  158. transition: all 0.6s cubic-bezier(0.34,1.56,0.64,1);
  159. }
  160. .cj-tile.g { background: var(--green); }
  161. .cj-tile.y { background: var(--yellow); }
  162. .cj-tile.w { background: var(--gray); }
  163. .cj-tile.shatter { filter: blur(8px); opacity: 0.2; transform: scale(0.8) rotate(15deg); }
  164. .realization-text {
  165. font-size: 1.2rem; color: var(--green); font-weight: 700;
  166. max-width: 600px; margin: 0 auto; opacity: 0; transition: opacity 0.8s 0.4s;
  167. }
  168. .realization-text.visible { opacity: 1; }
  169. /* ===== SYNTHESIS (CLIMAX) ===== */
  170. #synthesis { position: relative; }
  171. .synthesis-diagram {
  172. display: flex; justify-content: center; margin: 3rem 0;
  173. position: relative;
  174. }
  175. .synth-svg { width: 100%; max-width: 800px; height: auto; }
  176. .synth-node { fill: var(--card); stroke: #30363d; stroke-width: 1.5; }
  177. .synth-node.core { fill: #1a3320; stroke: var(--green); stroke-width: 2; }
  178. .synth-label { fill: var(--text); font-size: 11px; font-family: 'Segoe UI', system-ui, sans-serif; text-anchor: middle; }
  179. .synth-label.core { fill: var(--green); font-weight: 700; font-size: 13px; }
  180. .synth-line { stroke: #30363d; stroke-width: 1.5; fill: none; }
  181. .synth-line.hot { stroke: var(--green); stroke-width: 2; opacity: 0.6; }
  182. .synth-line.warm { stroke: var(--yellow); stroke-width: 1.5; opacity: 0.5; }
  183. /* ===== INSIGHTS ===== */
  184. #insights { }
  185. .insight-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1.5rem; }
  186. .insight-card {
  187. background: var(--card); border-radius: 12px; padding: 2rem;
  188. border-left: 4px solid var(--green);
  189. transition: transform 0.3s;
  190. }
  191. .insight-card:hover { transform: translateY(-3px); }
  192. .insight-card .num {
  193. font-size: 2.5rem; font-weight: 900; color: rgba(106,170,100,0.15);
  194. line-height: 1; margin-bottom: 0.5rem;
  195. }
  196. .insight-card .title { font-weight: 700; font-size: 1rem; margin-bottom: 0.5rem; color: var(--text); }
  197. .insight-card .detail { font-size: 0.9rem; color: var(--muted); line-height: 1.6; }
  198. /* ===== ANIMATIONS ===== */
  199. @keyframes fadeUp { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } }
  200. @keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.5; } }
  201. .reveal { opacity: 0; transform: translateY(30px); transition: opacity 0.7s ease-out, transform 0.7s ease-out; }
  202. .reveal.visible { opacity: 1; transform: translateY(0); }
  203. /* ===== TILE WAVE (HERO) ===== */
  204. @keyframes tilePop { 0% { transform: scale(0); opacity: 0; } 60% { transform: scale(1.2); } 100% { transform: scale(1); opacity: 1; } }
  205. .tile-pop { animation: tilePop 0.5s cubic-bezier(0.34,1.56,0.64,1) both; }
  206. /* ===== RESPONSIVE ===== */
  207. @media (max-width: 640px) {
  208. section { padding: 3rem 1rem; }
  209. .scamper-grid { grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); }
  210. .hero h1 { font-size: 1.8rem; }
  211. .tile { width: 40px; height: 40px; font-size: 1.1rem; }
  212. .cj-tile { width: 48px; height: 48px; font-size: 1.2rem; }
  213. #worstidea { border-radius: 12px; padding: 2rem 1rem; }
  214. }
  215. </style>
  216. </head>
  217. <body>
  218. <!-- ===== HERO ===== -->
  219. <section class="hero">
  220. <div class="hero-grid" id="heroTiles"></div>
  221. <h1>BUILDING A BETTER WORDLE</h1>
  222. <p class="subtitle">A brainstorm session exploring what a Wordle clone becomes when you question every assumption — then rebuild from first principles.</p>
  223. <p class="meta">July 7, 2026 &nbsp;·&nbsp; SCAMPER &nbsp;·&nbsp; What If &nbsp;·&nbsp; Worst Possible Idea &nbsp;·&nbsp; Kill the Crown Jewel</p>
  224. <div class="scroll-hint">Scroll to explore</div>
  225. </section>
  226. <!-- ============================================================ -->
  227. <!-- SCAMPER METHOD -->
  228. <!-- ============================================================ -->
  229. <section id="scamper" class="reveal">
  230. <div class="section-label">Technique One</div>
  231. <h2 class="section-title">The SCAMPER Method</h2>
  232. <p class="section-desc">
  233. Seven lenses applied to the core Wordle formula. Each letter opens a door to a different kind of reinvention — substitute the familiar, combine the unexpected, adapt to the player, modify what matters, put the mechanic to new use, eliminate the unnecessary, reverse the perspective.
  234. </p>
  235. <div class="scamper-grid">
  236. <div class="scamper-card" onclick="this.classList.toggle('expanded')">
  237. <div class="letter">S</div><div class="label">Substitute</div><div class="divider"></div>
  238. <div class="ideas">Variable word-length mode (3–7 letters) for fresh challenge dimensions. The 5-letter anchor stays for daily play, but substitution opens the game to broader word discovery.</div>
  239. </div>
  240. <div class="scamper-card" onclick="this.classList.toggle('expanded')">
  241. <div class="letter">C</div><div class="label">Combine</div><div class="divider"></div>
  242. <div class="ideas">Post-solve learning layer: definition, etymology, example sentence, and illustration. The game becomes a vocabulary builder — each solve is a micro-lesson you actually remember.</div>
  243. </div>
  244. <div class="scamper-card" onclick="this.classList.toggle('expanded')">
  245. <div class="letter">A</div><div class="label">Adapt</div><div class="divider"></div>
  246. <div class="ideas">Adaptive difficulty driven by global averages. Words self-sort into tiers — no pre-labeling. A hidden MMR/skill rating drifts with each performance, surfaced only as earned badges.</div>
  247. </div>
  248. <div class="scamper-card" onclick="this.classList.toggle('expanded')">
  249. <div class="letter">M</div><div class="label">Modify</div><div class="divider"></div>
  250. <div class="ideas">Percentile ranking instead of absolute position. "Top 15%" means something — "#14,327" means nothing. Streaks weighted by word difficulty: five hard-word wins beats ten easy ones.</div>
  251. </div>
  252. <div class="scamper-card" onclick="this.classList.toggle('expanded')">
  253. <div class="letter">P</div><div class="label">Put to Use</div><div class="divider"></div>
  254. <div class="ideas">Computer-guess subgame: you pick the word, the solver plays it back. Teaches strategy through observation. Optimal solver replays become a teaching moment post-solve.</div>
  255. </div>
  256. <div class="scamper-card" onclick="this.classList.toggle('expanded')">
  257. <div class="letter">E</div><div class="label">Eliminate</div><div class="divider"></div>
  258. <div class="ideas">No penalty for fast guessing — speed doesn't prove skill. No user-submitted words — curation matters. No obscure/archaic words — only vocabulary with recent internet-frequency usage.</div>
  259. </div>
  260. <div class="scamper-card" onclick="this.classList.toggle('expanded')">
  261. <div class="letter">R</div><div class="label">Reverse</div><div class="divider"></div>
  262. <div class="ideas">Reverse the roles. A computer-guess subgame where the player sets the target and watches the machine deduce. It measures true word complexity and teaches optimal strategy by demonstration.</div>
  263. </div>
  264. </div>
  265. </section>
  266. <!-- ============================================================ -->
  267. <!-- WHAT IF SCENARIOS -->
  268. <!-- ============================================================ -->
  269. <section id="whatif" class="reveal">
  270. <div class="section-label">Technique Two</div>
  271. <h2 class="section-title">What If Scenarios</h2>
  272. <p class="section-desc">
  273. Diverge without restraint. Each "what if" opens a branch — some lead to features, some to dead ends, and some reshape the entire product architecture. The branches that survive are the ones worth building.
  274. </p>
  275. <div class="branch-tree">
  276. <div class="branch-node">
  277. <div class="q">What if the daily word was just the beginning?</div>
  278. <div class="a"><span class="verdict accept">accepted</span> Daily word first, then prompt to continue — infinite play after the daily event. Two modes, one session.</div>
  279. </div>
  280. <div class="branch-node">
  281. <div class="q">What if we couldn't trust community-submitted words?</div>
  282. <div class="a"><span class="verdict reject">rejected</span> No user submissions. Word bank curated from recent internet-frequency usage only — nothing obscure, nothing archaic, everything solvable.</div>
  283. </div>
  284. <div class="branch-node">
  285. <div class="q">What if word length was variable?</div>
  286. <div class="a"><span class="verdict later">post-v1</span> 3-to-7-letter mode unlocks entirely new strategy spaces. Daily word stays at 5 — the variable mode is an optional skill expander.</div>
  287. </div>
  288. <div class="branch-node">
  289. <div class="q">What if position didn't matter?</div>
  290. <div class="a"><span class="verdict later">post-v1</span> Position-blind mode: yellow and gray only, no greens. A hard-mode variant that forces pure letter-set reasoning without positional crutches.</div>
  291. </div>
  292. <div class="branch-node">
  293. <div class="q">What if the target word changed each guess?</div>
  294. <div class="a"><span class="verdict later">post-v1</span> Rotating target — chaotic, disorienting, possibly brilliant. A variant for players who've mastered the standard constraints and crave chaos.</div>
  295. </div>
  296. <div class="branch-node">
  297. <div class="q">What if two players raced on the same word?</div>
  298. <div class="a"><span class="verdict later">post-v1</span> Real-time 2-player mode. Same word, simultaneous guesses. Social Wordle without the toxicity of direct competition — you share the word, not the scoreboard.</div>
  299. </div>
  300. </div>
  301. </section>
  302. <!-- ============================================================ -->
  303. <!-- WORST POSSIBLE IDEA -->
  304. <!-- ============================================================ -->
  305. <section id="worstidea" class="reveal">
  306. <div class="section-label">Technique Three</div>
  307. <h2 class="section-title">Worst Possible Idea</h2>
  308. <p class="section-desc" style="color:#4b5563;">
  309. Sometimes you find the boundary by crossing it. The worst ideas are mirrors — they show you, by inversion, what you actually value. Here, the worst idea revealed the irreducible core of the game.
  310. </p>
  311. <div class="glitch-container">
  312. <div class="glitch-ghost" aria-hidden="true">WORST IDEA</div>
  313. <div class="worst-idea-card">
  314. <div class="bad-idea">Replace green / yellow / gray position feedback with a single numeric distance score.</div>
  315. <p style="color:#4b5563; margin-top:0.8rem;">
  316. A single number — say, a Levenshtein distance or similarity percentage — replaces the colored tiles. No positional hints. No letter-level feedback. Just one opaque score per guess.
  317. </p>
  318. <div class="realization">
  319. Position feedback isn't decoration — it's the compression algorithm that makes 5-letter words solvable in 6 attempts. Without it, you'd need 12+ guesses. The green/yellow/gray system is a brilliantly efficient information channel. It stays.
  320. </div>
  321. </div>
  322. </div>
  323. </section>
  324. <!-- ============================================================ -->
  325. <!-- KILL THE CROWN JEWEL -->
  326. <!-- ============================================================ -->
  327. <section id="crownjewel" class="reveal">
  328. <div class="section-label">Technique Four</div>
  329. <h2 class="section-title">Kill the Crown Jewel</h2>
  330. <p class="section-desc">
  331. The crown jewel of Wordle is its tri-color position feedback. What if we killed it? Below, the tiles shatter — and what emerges from the wreckage is the realization of why they're indispensable.
  332. </p>
  333. <div class="crown-tiles" id="crownTiles">
  334. <div class="cj-tile g">G</div>
  335. <div class="cj-tile y">Y</div>
  336. <div class="cj-tile w">W</div>
  337. <div class="cj-tile g">G</div>
  338. <div class="cj-tile y">Y</div>
  339. </div>
  340. <button id="killBtn" style="
  341. background: transparent; border: 2px solid #30363d; color: var(--muted);
  342. padding: 0.6rem 1.8rem; border-radius: 24px; cursor: pointer;
  343. font-size: 0.9rem; letter-spacing: 0.05em; transition: all 0.3s;
  344. margin-bottom: 1.5rem;
  345. " onmouseover="this.style.borderColor='#f85149';this.style.color='#f85149'"
  346. onmouseout="this.style.borderColor='#30363d';this.style.color='var(--muted)'">
  347. KILL THE CROWN JEWEL
  348. </button>
  349. <div class="realization-text" id="cjRealization">
  350. Green / yellow / gray feedback is the irreducible minimum. It's the game's entire information architecture compressed into three colors. Remove it and you don't have a harder Wordle — you don't have Wordle at all. The constraint of 5 letters and 6 attempts only works <em>because</em> each guess delivers 5 data points of positional truth. Kill the crown jewel and the whole system collapses. So we keep it — and build everything else around it.
  351. </div>
  352. </section>
  353. <!-- ============================================================ -->
  354. <!-- SYNTHESIS — THE CLIMAX -->
  355. <!-- ============================================================ -->
  356. <section id="synthesis" class="reveal">
  357. <div class="section-label">Synthesis</div>
  358. <h2 class="section-title">The Unified System</h2>
  359. <p class="section-desc">
  360. Every surviving idea from every technique converges into a single coherent architecture. The solver engine is the gravitational center — it drives difficulty tiering, validates word solvability, generates baseline percentiles, and powers the teaching layer. Everything connects.
  361. </p>
  362. <div class="synthesis-diagram">
  363. <svg class="synth-svg" viewBox="0 0 800 620" xmlns="http://www.w3.org/2000/svg">
  364. <!-- Connection lines -->
  365. <!-- Core to Tiering -->
  366. <line class="synth-line hot" x1="400" y1="200" x2="160" y2="340"/>
  367. <!-- Core to Percentile -->
  368. <line class="synth-line hot" x1="400" y1="200" x2="400" y2="370"/>
  369. <!-- Core to Adaptive/MMR -->
  370. <line class="synth-line hot" x1="400" y1="200" x2="640" y2="340"/>
  371. <!-- Core to Word Curation -->
  372. <line class="synth-line warm" x1="400" y1="200" x2="120" y2="510"/>
  373. <!-- Core to Learning -->
  374. <line class="synth-line warm" x1="400" y1="200" x2="400" y2="520"/>
  375. <!-- Core to Hints -->
  376. <line class="synth-line warm" x1="400" y1="200" x2="680" y2="510"/>
  377. <!-- Tiering to Adaptive -->
  378. <line class="synth-line warm" x1="160" y1="340" x2="640" y2="340"/>
  379. <!-- Tiering to Percentile -->
  380. <line class="synth-line warm" x1="160" y1="340" x2="400" y2="370"/>
  381. <!-- Percentile to Adaptive -->
  382. <line class="synth-line warm" x1="400" y1="370" x2="640" y2="340"/>
  383. <!-- Percentile to Streaks -->
  384. <line class="synth-line warm" x1="400" y1="370" x2="400" y2="460"/>
  385. <!-- Learning to Subgame -->
  386. <line class="synth-line warm" x1="400" y1="520" x2="260" y2="570"/>
  387. <!-- Hints to Retention -->
  388. <line class="synth-line warm" x1="680" y1="510" x2="540" y2="570"/>
  389. <!-- NODES -->
  390. <!-- Core Engine -->
  391. <rect class="synth-node core" x="310" y="145" width="180" height="55" rx="28"/>
  392. <text class="synth-label core" x="400" y="178">SOLVER ENGINE</text>
  393. <!-- Word Difficulty Tiering -->
  394. <rect class="synth-node" x="55" y="315" width="210" height="50" rx="10"/>
  395. <text class="synth-label" x="160" y="336">Word Difficulty Tiers</text>
  396. <text class="synth-label" x="160" y="352" style="fill:var(--muted);font-size:9px;">self-sorting by global averages</text>
  397. <!-- Percentile Ranking -->
  398. <rect class="synth-node" x="295" y="345" width="210" height="50" rx="10"/>
  399. <text class="synth-label" x="400" y="366">Percentile Ranking</text>
  400. <text class="synth-label" x="400" y="382" style="fill:var(--muted);font-size:9px;">computer baseline as reference</text>
  401. <!-- Adaptive Difficulty / MMR -->
  402. <rect class="synth-node" x="535" y="315" width="210" height="50" rx="10"/>
  403. <text class="synth-label" x="640" y="336">Adaptive Difficulty &amp; MMR</text>
  404. <text class="synth-label" x="640" y="352" style="fill:var(--muted);font-size:9px;">hidden skill rating, surfaceable badges</text>
  405. <!-- Quality-Weighted Streaks -->
  406. <rect class="synth-node" x="310" y="435" width="180" height="50" rx="10"/>
  407. <text class="synth-label" x="400" y="456">Quality Streaks</text>
  408. <text class="synth-label" x="400" y="472" style="fill:var(--muted);font-size:9px;">hard-word streak &gt; easy-word streak</text>
  409. <!-- Word Curation -->
  410. <rect class="synth-node" x="15" y="485" width="210" height="50" rx="10"/>
  411. <text class="synth-label" x="120" y="506">Word Curation</text>
  412. <text class="synth-label" x="120" y="522" style="fill:var(--muted);font-size:9px;">frequency-filtered, solvability-validated</text>
  413. <!-- Post-Solve Learning -->
  414. <rect class="synth-node" x="295" y="495" width="210" height="50" rx="10"/>
  415. <text class="synth-label" x="400" y="516">Post-Solve Learning Layer</text>
  416. <text class="synth-label" x="400" y="532" style="fill:var(--muted);font-size:9px;">definition · etymology · example · image</text>
  417. <!-- Standardized Hints -->
  418. <rect class="synth-node" x="575" y="485" width="210" height="50" rx="10"/>
  419. <text class="synth-label" x="680" y="506">Standardized Hints</text>
  420. <text class="synth-label" x="680" y="522" style="fill:var(--muted);font-size:9px;">6th-attempt safety net, fair to all</text>
  421. <!-- Computer Subgame -->
  422. <rect class="synth-node" x="155" y="555" width="210" height="50" rx="10"/>
  423. <text class="synth-label" x="260" y="576">Computer Subgame</text>
  424. <text class="synth-label" x="260" y="592" style="fill:var(--muted);font-size:9px;">teach strategy through solver replays</text>
  425. <!-- Retention -->
  426. <rect class="synth-node" x="435" y="555" width="210" height="50" rx="10"/>
  427. <text class="synth-label" x="540" y="576">Retention</text>
  428. <text class="synth-label" x="540" y="592" style="fill:var(--muted);font-size:9px;">daily → infinite flow, catch failing players</text>
  429. <!-- Flow annotations -->
  430. <text style="fill:var(--green);font-size:9px;opacity:0.7;" x="498" y="265">difficulty data</text>
  431. <text style="fill:var(--green);font-size:9px;opacity:0.7;" x="498" y="280">flows to all subsystems</text>
  432. </svg>
  433. </div>
  434. </section>
  435. <!-- ============================================================ -->
  436. <!-- INSIGHTS -->
  437. <!-- ============================================================ -->
  438. <section id="insights" class="reveal">
  439. <div class="section-label">Takeaways</div>
  440. <h2 class="section-title">Four Insights That Define the Architecture</h2>
  441. <div class="insight-cards">
  442. <div class="insight-card">
  443. <div class="num">01</div>
  444. <div class="title">One Engine, Many Purposes</div>
  445. <div class="detail">The computer solver baseline isn't a feature — it's infrastructure. The same engine drives word difficulty tiering, percentile ranking baselines, solvability validation for curation, and the teaching replays. Build it once; it feeds everything.</div>
  446. </div>
  447. <div class="insight-card">
  448. <div class="num">02</div>
  449. <div class="title">Leaderboard Without Toxicity</div>
  450. <div class="detail">Percentile ranking and quality-weighted streaks together create competitive motivation without the zero-sum anxiety of absolute ranks. You're not #14,327 — you're in the top 12% on a hard-word streak. That feels earned, not compared.</div>
  451. </div>
  452. <div class="insight-card">
  453. <div class="num">03</div>
  454. <div class="title">The Solve Is Where Learning Begins</div>
  455. <div class="detail">Post-solve is the moment of maximum curiosity. Show the definition, etymology, and example sentence right then — plus an optimal solver replay. The player just invested mental effort in the word; now they'll actually remember what it means.</div>
  456. </div>
  457. <div class="insight-card">
  458. <div class="num">04</div>
  459. <div class="title">Standardized Hints Are a Retention Mechanic</div>
  460. <div class="detail">A weak hint on the 5th attempt and a stronger one on the 6th — identical for every player — catches struggling players before they bounce. Good players solve in 4 or fewer, so the hint doesn't distort stats. It just keeps people in the game.</div>
  461. </div>
  462. </div>
  463. </section>
  464. <!-- ============================================================ -->
  465. <!-- FOOTER -->
  466. <!-- ============================================================ -->
  467. <footer style="text-align:center; padding:4rem 2rem; color:#30363d; font-size:0.8rem;">
  468. Wordle Clone Brainstorm &nbsp;·&nbsp; July 7, 2026 &nbsp;·&nbsp; 5-letter words &nbsp;·&nbsp; 6 attempts &nbsp;·&nbsp; infinite possibilities
  469. </footer>
  470. <!-- ============================================================ -->
  471. <!-- SCRIPTS -->
  472. <!-- ============================================================ -->
  473. <script>
  474. (function(){
  475. /* --- HERO TILE ANIMATION --- */
  476. const word = 'BRAINSTORM';
  477. const colors = ['green','gray','green','yellow','gray','green','green','yellow','gray','green'];
  478. const heroGrid = document.getElementById('heroTiles');
  479. word.split('').forEach((ch,i) => {
  480. const span = document.createElement('span');
  481. span.className = 'tile ' + colors[i] + ' tile-pop';
  482. span.style.animationDelay = (i * 0.08) + 's';
  483. span.textContent = ch;
  484. heroGrid.appendChild(span);
  485. });
  486. /* --- KILL THE CROWN JEWEL --- */
  487. const killBtn = document.getElementById('killBtn');
  488. const cjReal = document.getElementById('cjRealization');
  489. const tiles = document.querySelectorAll('.cj-tile');
  490. let killed = false;
  491. killBtn.addEventListener('click', () => {
  492. if (killed) {
  493. tiles.forEach(t => t.classList.remove('shatter'));
  494. cjReal.classList.remove('visible');
  495. killBtn.textContent = 'KILL THE CROWN JEWEL';
  496. killed = false;
  497. } else {
  498. tiles.forEach((t,i) => {
  499. setTimeout(() => t.classList.add('shatter'), i * 120);
  500. });
  501. setTimeout(() => cjReal.classList.add('visible'), 800);
  502. killBtn.textContent = 'RESTORE THE CROWN JEWEL';
  503. killed = true;
  504. }
  505. });
  506. /* --- SCROLL REVEAL --- */
  507. const observer = new IntersectionObserver((entries) => {
  508. entries.forEach(entry => {
  509. if (entry.isIntersecting) {
  510. entry.target.classList.add('visible');
  511. }
  512. });
  513. }, { threshold: 0.15 });
  514. document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
  515. })();
  516. </script>
  517. </body>
  518. </html>