Spaces:
Running
Running
fix: improve UI consistency and prevent capitalized words as blanks
Browse files- Exclude capitalized words from blank selection in all word selection paths
- Normalize button sizes across the application for better proportions
- Use accessible font family consistently throughout UI elements
- Improve input field spacing and placeholder formatting
- Remove unnecessary gaps between input fields and chat buttons
- src/clozeGameEngine.js +26 -16
- src/styles.css +60 -31
src/clozeGameEngine.js
CHANGED
|
@@ -309,19 +309,23 @@ class ClozeGame {
|
|
| 309 |
|
| 310 |
let wordIndex = -1;
|
| 311 |
|
| 312 |
-
// First try to find the word in the designated section (avoiding first 10 words)
|
| 313 |
for (let i = Math.max(10, sectionStart); i < sectionEnd; i++) {
|
| 314 |
-
|
|
|
|
|
|
|
| 315 |
wordIndex = i;
|
| 316 |
break;
|
| 317 |
}
|
| 318 |
}
|
| 319 |
|
| 320 |
-
// If not found in section, look globally (but still avoid first 10 words)
|
| 321 |
if (wordIndex === -1) {
|
| 322 |
-
wordIndex = wordsLower.findIndex((word, idx) =>
|
| 323 |
-
|
| 324 |
-
|
|
|
|
|
|
|
| 325 |
}
|
| 326 |
|
| 327 |
if (wordIndex !== -1) {
|
|
@@ -339,12 +343,14 @@ class ClozeGame {
|
|
| 339 |
console.warn('No AI words matched in passage, using manual selection');
|
| 340 |
const manualWords = this.selectWordsManually(words, numberOfBlanks);
|
| 341 |
|
| 342 |
-
// Try to match manual words (avoiding first 10 words)
|
| 343 |
manualWords.forEach((manualWord, index) => {
|
| 344 |
const cleanManual = manualWord.toLowerCase().replace(/[^\w]/g, '');
|
| 345 |
-
const wordIndex = wordsLower.findIndex((word, idx) =>
|
| 346 |
-
|
| 347 |
-
|
|
|
|
|
|
|
| 348 |
|
| 349 |
if (wordIndex !== -1) {
|
| 350 |
selectedIndices.push(wordIndex);
|
|
@@ -459,7 +465,11 @@ class ClozeGame {
|
|
| 459 |
const contentWordIndices = [];
|
| 460 |
words.forEach((word, index) => {
|
| 461 |
const cleanWord = word.toLowerCase().replace(/[^\w]/g, '');
|
| 462 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 463 |
contentWordIndices.push({ word: cleanWord, index });
|
| 464 |
}
|
| 465 |
});
|
|
@@ -519,8 +529,8 @@ class ClozeGame {
|
|
| 519 |
const inputHtml = `<input type="text"
|
| 520 |
class="cloze-input"
|
| 521 |
data-blank-index="${index}"
|
| 522 |
-
placeholder="${'_
|
| 523 |
-
style="width: ${Math.max(
|
| 524 |
|
| 525 |
html = html.replace(`___BLANK_${index}___`, inputHtml);
|
| 526 |
});
|
|
@@ -731,12 +741,12 @@ class ClozeGame {
|
|
| 731 |
this.blanks.forEach((blank, index) => {
|
| 732 |
const chatButtonId = `chat-btn-${index}`;
|
| 733 |
const inputHtml = `
|
| 734 |
-
<span class="inline-flex items-center
|
| 735 |
<input type="text"
|
| 736 |
class="cloze-input"
|
| 737 |
data-blank-index="${index}"
|
| 738 |
-
placeholder="${'_
|
| 739 |
-
style="width: ${Math.max(
|
| 740 |
<button id="${chatButtonId}"
|
| 741 |
class="chat-button text-blue-500 hover:text-blue-700 text-sm"
|
| 742 |
data-blank-index="${index}"
|
|
|
|
| 309 |
|
| 310 |
let wordIndex = -1;
|
| 311 |
|
| 312 |
+
// First try to find the word in the designated section (avoiding first 10 words and capitalized words)
|
| 313 |
for (let i = Math.max(10, sectionStart); i < sectionEnd; i++) {
|
| 314 |
+
const originalWord = words[i].replace(/[^\w]/g, '');
|
| 315 |
+
const isCapitalized = originalWord.length > 0 && originalWord[0] === originalWord[0].toUpperCase();
|
| 316 |
+
if (wordsLower[i] === cleanSignificant && !selectedIndices.includes(i) && !isCapitalized) {
|
| 317 |
wordIndex = i;
|
| 318 |
break;
|
| 319 |
}
|
| 320 |
}
|
| 321 |
|
| 322 |
+
// If not found in section, look globally (but still avoid first 10 words and capitalized words)
|
| 323 |
if (wordIndex === -1) {
|
| 324 |
+
wordIndex = wordsLower.findIndex((word, idx) => {
|
| 325 |
+
const originalWord = words[idx].replace(/[^\w]/g, '');
|
| 326 |
+
const isCapitalized = originalWord.length > 0 && originalWord[0] === originalWord[0].toUpperCase();
|
| 327 |
+
return word === cleanSignificant && !selectedIndices.includes(idx) && idx >= 10 && !isCapitalized;
|
| 328 |
+
});
|
| 329 |
}
|
| 330 |
|
| 331 |
if (wordIndex !== -1) {
|
|
|
|
| 343 |
console.warn('No AI words matched in passage, using manual selection');
|
| 344 |
const manualWords = this.selectWordsManually(words, numberOfBlanks);
|
| 345 |
|
| 346 |
+
// Try to match manual words (avoiding first 10 words and capitalized words)
|
| 347 |
manualWords.forEach((manualWord, index) => {
|
| 348 |
const cleanManual = manualWord.toLowerCase().replace(/[^\w]/g, '');
|
| 349 |
+
const wordIndex = wordsLower.findIndex((word, idx) => {
|
| 350 |
+
const originalWord = words[idx].replace(/[^\w]/g, '');
|
| 351 |
+
const isCapitalized = originalWord.length > 0 && originalWord[0] === originalWord[0].toUpperCase();
|
| 352 |
+
return word === cleanManual && !selectedIndices.includes(idx) && idx >= 10 && !isCapitalized;
|
| 353 |
+
});
|
| 354 |
|
| 355 |
if (wordIndex !== -1) {
|
| 356 |
selectedIndices.push(wordIndex);
|
|
|
|
| 465 |
const contentWordIndices = [];
|
| 466 |
words.forEach((word, index) => {
|
| 467 |
const cleanWord = word.toLowerCase().replace(/[^\w]/g, '');
|
| 468 |
+
const originalCleanWord = word.replace(/[^\w]/g, '');
|
| 469 |
+
// Skip capitalized words, function words, and words that are too short/long
|
| 470 |
+
if (cleanWord.length > 3 && cleanWord.length <= 12 &&
|
| 471 |
+
!functionWords.has(cleanWord) &&
|
| 472 |
+
originalCleanWord[0] === originalCleanWord[0].toLowerCase()) {
|
| 473 |
contentWordIndices.push({ word: cleanWord, index });
|
| 474 |
}
|
| 475 |
});
|
|
|
|
| 529 |
const inputHtml = `<input type="text"
|
| 530 |
class="cloze-input"
|
| 531 |
data-blank-index="${index}"
|
| 532 |
+
placeholder="${'_'.repeat(Math.max(3, blank.originalWord.length))}"
|
| 533 |
+
style="width: ${Math.max(70, blank.originalWord.length * 14)}px;">`;
|
| 534 |
|
| 535 |
html = html.replace(`___BLANK_${index}___`, inputHtml);
|
| 536 |
});
|
|
|
|
| 741 |
this.blanks.forEach((blank, index) => {
|
| 742 |
const chatButtonId = `chat-btn-${index}`;
|
| 743 |
const inputHtml = `
|
| 744 |
+
<span class="inline-flex items-center">
|
| 745 |
<input type="text"
|
| 746 |
class="cloze-input"
|
| 747 |
data-blank-index="${index}"
|
| 748 |
+
placeholder="${'_'.repeat(Math.max(3, blank.originalWord.length))}"
|
| 749 |
+
style="width: ${Math.max(70, blank.originalWord.length * 14)}px;">
|
| 750 |
<button id="${chatButtonId}"
|
| 751 |
class="chat-button text-blue-500 hover:text-blue-700 text-sm"
|
| 752 |
data-blank-index="${index}"
|
src/styles.css
CHANGED
|
@@ -31,6 +31,33 @@
|
|
| 31 |
transform: scale(1.1);
|
| 32 |
}
|
| 33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
.suggestion-btn, .question-btn {
|
| 35 |
transition: all 0.2s ease;
|
| 36 |
padding: 14px 18px;
|
|
@@ -121,8 +148,11 @@
|
|
| 121 |
background: #1f2937;
|
| 122 |
color: white;
|
| 123 |
border: 2px solid #374151;
|
| 124 |
-
padding:
|
| 125 |
font-weight: 600;
|
|
|
|
|
|
|
|
|
|
| 126 |
transition: all 0.2s ease;
|
| 127 |
}
|
| 128 |
|
|
@@ -228,8 +258,8 @@
|
|
| 228 |
color: var(--typewriter-ink);
|
| 229 |
text-align: center;
|
| 230 |
outline: none;
|
| 231 |
-
padding: 4px
|
| 232 |
-
margin: 0
|
| 233 |
min-width: 4ch;
|
| 234 |
width: auto;
|
| 235 |
font-size: inherit;
|
|
@@ -262,20 +292,20 @@
|
|
| 262 |
|
| 263 |
.typewriter-button {
|
| 264 |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
| 265 |
-
min-width:
|
| 266 |
-
min-height:
|
| 267 |
-
padding:
|
| 268 |
background-color: var(--aged-paper-dark);
|
| 269 |
color: var(--typewriter-ink);
|
| 270 |
border: 2px solid black;
|
| 271 |
border-radius: 6px;
|
| 272 |
font-weight: 600;
|
| 273 |
-
font-size:
|
| 274 |
cursor: pointer;
|
| 275 |
transition: all 0.15s ease;
|
| 276 |
box-shadow:
|
| 277 |
-
0
|
| 278 |
-
0
|
| 279 |
position: relative;
|
| 280 |
overflow: hidden;
|
| 281 |
}
|
|
@@ -284,15 +314,15 @@
|
|
| 284 |
background-color: rgba(0, 0, 0, 0.05);
|
| 285 |
transform: translateY(-1px);
|
| 286 |
box-shadow:
|
| 287 |
-
0
|
| 288 |
-
0
|
| 289 |
}
|
| 290 |
|
| 291 |
.typewriter-button:active:not(:disabled) {
|
| 292 |
transform: translateY(2px);
|
| 293 |
box-shadow:
|
| 294 |
-
0
|
| 295 |
-
0
|
| 296 |
}
|
| 297 |
|
| 298 |
.typewriter-button:disabled {
|
|
@@ -326,28 +356,25 @@
|
|
| 326 |
}
|
| 327 |
|
| 328 |
.biblio-info {
|
| 329 |
-
font-family: '
|
| 330 |
font-size: 0.85rem;
|
| 331 |
color: #666;
|
| 332 |
-
letter-spacing: 0.03em;
|
| 333 |
font-style: italic;
|
| 334 |
}
|
| 335 |
|
| 336 |
.context-box {
|
| 337 |
background-color: rgba(245, 158, 11, 0.08);
|
| 338 |
border-left: 4px solid #f59e0b;
|
| 339 |
-
font-family: '
|
| 340 |
font-size: 0.9rem;
|
| 341 |
-
letter-spacing: 0.03em;
|
| 342 |
line-height: 1.6;
|
| 343 |
}
|
| 344 |
|
| 345 |
.hints-box {
|
| 346 |
background-color: rgba(245, 158, 11, 0.08);
|
| 347 |
border-left: 4px solid #f59e0b;
|
| 348 |
-
font-family: '
|
| 349 |
font-size: 0.9rem;
|
| 350 |
-
letter-spacing: 0.03em;
|
| 351 |
line-height: 1.6;
|
| 352 |
}
|
| 353 |
|
|
@@ -355,21 +382,23 @@
|
|
| 355 |
background-color: rgba(245, 158, 11, 0.1);
|
| 356 |
color: #666;
|
| 357 |
border: 1px solid rgba(245, 158, 11, 0.2);
|
| 358 |
-
font-family: '
|
| 359 |
font-weight: 600;
|
| 360 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 361 |
}
|
| 362 |
|
| 363 |
.loading-text {
|
| 364 |
-
font-family: '
|
| 365 |
color: #666;
|
| 366 |
-
letter-spacing: 0.05em;
|
| 367 |
}
|
| 368 |
|
| 369 |
.result-text {
|
| 370 |
-
font-family: '
|
| 371 |
font-weight: 600;
|
| 372 |
-
letter-spacing: 0.05em;
|
| 373 |
}
|
| 374 |
|
| 375 |
/* Responsive adjustments */
|
|
@@ -419,20 +448,20 @@
|
|
| 419 |
|
| 420 |
/* Mobile dropdown styling */
|
| 421 |
#question-dropdown {
|
| 422 |
-
background:
|
| 423 |
-
border: 2px solid
|
| 424 |
border-radius: 8px;
|
| 425 |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
| 426 |
-
font-size:
|
| 427 |
font-weight: 500;
|
| 428 |
-
color:
|
| 429 |
transition: all 0.2s ease;
|
| 430 |
}
|
| 431 |
|
| 432 |
#question-dropdown:focus {
|
| 433 |
outline: none;
|
| 434 |
-
border-color:
|
| 435 |
-
box-shadow: 0 0 0 3px rgba(0,
|
| 436 |
}
|
| 437 |
|
| 438 |
/* Print styles */
|
|
|
|
| 31 |
transform: scale(1.1);
|
| 32 |
}
|
| 33 |
|
| 34 |
+
/* Chat modal styling to match game font */
|
| 35 |
+
#chat-modal {
|
| 36 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
#chat-modal .bg-white {
|
| 40 |
+
background-color: var(--aged-paper-light);
|
| 41 |
+
border: 2px solid rgba(0, 0, 0, 0.1);
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
#chat-modal h3 {
|
| 45 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
| 46 |
+
color: var(--typewriter-ink);
|
| 47 |
+
font-weight: 600;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
#chat-messages {
|
| 51 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
| 52 |
+
color: var(--typewriter-ink);
|
| 53 |
+
line-height: 1.6;
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
#chat-messages .text-gray-500 {
|
| 57 |
+
color: #666 !important;
|
| 58 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
.suggestion-btn, .question-btn {
|
| 62 |
transition: all 0.2s ease;
|
| 63 |
padding: 14px 18px;
|
|
|
|
| 148 |
background: #1f2937;
|
| 149 |
color: white;
|
| 150 |
border: 2px solid #374151;
|
| 151 |
+
padding: 8px 14px;
|
| 152 |
font-weight: 600;
|
| 153 |
+
font-size: 14px;
|
| 154 |
+
min-width: 100px;
|
| 155 |
+
min-height: 36px;
|
| 156 |
transition: all 0.2s ease;
|
| 157 |
}
|
| 158 |
|
|
|
|
| 258 |
color: var(--typewriter-ink);
|
| 259 |
text-align: center;
|
| 260 |
outline: none;
|
| 261 |
+
padding: 3px 4px;
|
| 262 |
+
margin: 0 1px;
|
| 263 |
min-width: 4ch;
|
| 264 |
width: auto;
|
| 265 |
font-size: inherit;
|
|
|
|
| 292 |
|
| 293 |
.typewriter-button {
|
| 294 |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
| 295 |
+
min-width: 100px;
|
| 296 |
+
min-height: 36px;
|
| 297 |
+
padding: 8px 14px;
|
| 298 |
background-color: var(--aged-paper-dark);
|
| 299 |
color: var(--typewriter-ink);
|
| 300 |
border: 2px solid black;
|
| 301 |
border-radius: 6px;
|
| 302 |
font-weight: 600;
|
| 303 |
+
font-size: 14px;
|
| 304 |
cursor: pointer;
|
| 305 |
transition: all 0.15s ease;
|
| 306 |
box-shadow:
|
| 307 |
+
0 3px 0 rgba(0, 0, 0, 0.3),
|
| 308 |
+
0 4px 8px rgba(0, 0, 0, 0.1);
|
| 309 |
position: relative;
|
| 310 |
overflow: hidden;
|
| 311 |
}
|
|
|
|
| 314 |
background-color: rgba(0, 0, 0, 0.05);
|
| 315 |
transform: translateY(-1px);
|
| 316 |
box-shadow:
|
| 317 |
+
0 4px 0 rgba(0, 0, 0, 0.3),
|
| 318 |
+
0 6px 12px rgba(0, 0, 0, 0.15);
|
| 319 |
}
|
| 320 |
|
| 321 |
.typewriter-button:active:not(:disabled) {
|
| 322 |
transform: translateY(2px);
|
| 323 |
box-shadow:
|
| 324 |
+
0 1px 0 rgba(0, 0, 0, 0.3),
|
| 325 |
+
0 2px 4px rgba(0, 0, 0, 0.1);
|
| 326 |
}
|
| 327 |
|
| 328 |
.typewriter-button:disabled {
|
|
|
|
| 356 |
}
|
| 357 |
|
| 358 |
.biblio-info {
|
| 359 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
| 360 |
font-size: 0.85rem;
|
| 361 |
color: #666;
|
|
|
|
| 362 |
font-style: italic;
|
| 363 |
}
|
| 364 |
|
| 365 |
.context-box {
|
| 366 |
background-color: rgba(245, 158, 11, 0.08);
|
| 367 |
border-left: 4px solid #f59e0b;
|
| 368 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
| 369 |
font-size: 0.9rem;
|
|
|
|
| 370 |
line-height: 1.6;
|
| 371 |
}
|
| 372 |
|
| 373 |
.hints-box {
|
| 374 |
background-color: rgba(245, 158, 11, 0.08);
|
| 375 |
border-left: 4px solid #f59e0b;
|
| 376 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
| 377 |
font-size: 0.9rem;
|
|
|
|
| 378 |
line-height: 1.6;
|
| 379 |
}
|
| 380 |
|
|
|
|
| 382 |
background-color: rgba(245, 158, 11, 0.1);
|
| 383 |
color: #666;
|
| 384 |
border: 1px solid rgba(245, 158, 11, 0.2);
|
| 385 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
| 386 |
font-weight: 600;
|
| 387 |
+
}
|
| 388 |
+
|
| 389 |
+
/* Ensure specific game info elements use accessible font */
|
| 390 |
+
#book-info, #round-info, #contextualization {
|
| 391 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
| 392 |
}
|
| 393 |
|
| 394 |
.loading-text {
|
| 395 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
| 396 |
color: #666;
|
|
|
|
| 397 |
}
|
| 398 |
|
| 399 |
.result-text {
|
| 400 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
| 401 |
font-weight: 600;
|
|
|
|
| 402 |
}
|
| 403 |
|
| 404 |
/* Responsive adjustments */
|
|
|
|
| 448 |
|
| 449 |
/* Mobile dropdown styling */
|
| 450 |
#question-dropdown {
|
| 451 |
+
background: var(--aged-paper-dark);
|
| 452 |
+
border: 2px solid rgba(0, 0, 0, 0.1);
|
| 453 |
border-radius: 8px;
|
| 454 |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
| 455 |
+
font-size: 16px;
|
| 456 |
font-weight: 500;
|
| 457 |
+
color: var(--typewriter-ink);
|
| 458 |
transition: all 0.2s ease;
|
| 459 |
}
|
| 460 |
|
| 461 |
#question-dropdown:focus {
|
| 462 |
outline: none;
|
| 463 |
+
border-color: rgba(0, 0, 0, 0.3);
|
| 464 |
+
box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.1);
|
| 465 |
}
|
| 466 |
|
| 467 |
/* Print styles */
|