diff --git a/index.html b/index.html index b7684f0..03f6918 100644 --- a/index.html +++ b/index.html @@ -193,24 +193,43 @@ .definition-split { display: flex; + flex-direction: column; position: absolute; inset: 0; } .definition-half { - width: 50%; + height: 50%; position: relative; padding: 2px; - font-size: 5px; - line-height: 6px; + font-size: 8px; + line-height: 10px; overflow: hidden; word-wrap: break-word; + display:flex; + align-items:center; + justify-content:center; + font-variant: small-caps; + text-transform:uppercase; } .definition-half:first-child { - border-right: 1px solid #6b7280; + border-bottom: 1px solid #6b7280; } + .definition-text { + font-variant: small-caps; + text-transform:uppercase; + font-size:10px; + display:flex; + align-items:center; + justify-content:center; + } + + .definition-item.selected { background-color: #fde68a; } + + .def-arrow { position:absolute; pointer-events:none; } + /* Visual hint for hyphens: dotted border between cells */ .cell.hyphen { border-right: 2px dotted #000; @@ -350,7 +369,9 @@
-
+
+ +
@@ -516,12 +537,20 @@ // Gère le double-clic function handleCellDoubleClick(row, col) { const cell = grid[row][col]; - cell.type = cell.type === 'letter' ? 'definition' : 'letter'; - if (cell.type === 'letter') { + if (cell.type === 'letter' && !cell.letter) { + // empty letter -> become empty definition + cell.type = 'definition'; cell.definitionH = ''; cell.definitionV = ''; } else { - cell.letter = ''; + // otherwise toggle + cell.type = cell.type === 'letter' ? 'definition' : 'letter'; + if (cell.type === 'letter') { + cell.definitionH = ''; + cell.definitionV = ''; + } else { + cell.letter = ''; + } } renderGrid(); } @@ -558,6 +587,7 @@ const btn = document.createElement('button'); btn.className = 'definition-item'; btn.textContent = def; + if (grid[row][col].definitionH === def) btn.classList.add('selected'); btn.onclick = () => { grid[row][col].definitionH = def; closeModal(); @@ -593,6 +623,7 @@ const btn = document.createElement('button'); btn.className = 'definition-item'; btn.textContent = def; + if (grid[row][col].definitionV === def) btn.classList.add('selected'); btn.onclick = () => { grid[row][col].definitionV = def; closeModal(); @@ -893,83 +924,85 @@ gridEl.appendChild(addRowLine); // After grid built, place arrows in the first-letter cells based on adjacent definition cells - // Clear any previous arrows if (window._cellEls) { for (let r = 0; r < grid.length; r++) { for (let c = 0; c < grid[0].length; c++) { const el = window._cellEls[r] && window._cellEls[r][c]; if (el) { - const prev = el.querySelector('.def-arrow'); - if (prev) prev.remove(); + const prev = el.querySelectorAll('.def-arrow'); + prev.forEach(p => p.remove()); } } } - // For each definition cell, compute target first-letter cell and append arrow there for (let dr = 0; dr < grid.length; dr++) { for (let dc = 0; dc < grid[0].length; dc++) { const defCell = grid[dr][dc]; if (defCell.type !== 'definition') continue; - // Horizontal-definition mapping - if (defCell.definitionH) { - const tr = dr; - const tc = dc + 1; - if (tr >= 0 && tr < grid.length && tc >= 0 && tc < grid[0].length) { - const targetEl = window._cellEls[tr] && window._cellEls[tr][tc]; - if (targetEl) { - const arrow = document.createElement('div'); - arrow.className = 'def-arrow'; - // special top-row: curve down - if (dr === 0) { - arrow.innerHTML = ''; - arrow.style.position = 'absolute'; - arrow.style.top = '2px'; - arrow.style.left = '50%'; - arrow.style.transform = 'translateX(-50%)'; - } else { - // left-pointing arrow near left border - arrow.innerHTML = ''; - arrow.style.position = 'absolute'; - arrow.style.left = '4px'; - arrow.style.top = '50%'; - arrow.style.transform = 'translateY(-50%)'; - } - arrow.style.pointerEvents = 'none'; - arrow.classList.add('def-arrow'); - targetEl.appendChild(arrow); + // Horizontal mapping: def at (dr,dc) -> word starts at (dr,dc+1) normally + let trH = dr; + let tcH = dc + 1; + // top-row special: horizontal definition maps to vertical word starting at (dr,dc+1) + let horizontalIsVertical = false; + if (dr === 0) { + horizontalIsVertical = true; + trH = dr; + tcH = dc + 1; + } + + if (defCell.definitionH && tcH < grid[0].length) { + const targetEl = window._cellEls[trH] && window._cellEls[trH][tcH]; + if (targetEl) { + const arrow = document.createElement('div'); + arrow.className = 'def-arrow'; + if (horizontalIsVertical) { + // arrow downwards from top border + arrow.innerHTML = ''; + arrow.style.top = '0px'; + arrow.style.left = '50%'; + arrow.style.transform = 'translateX(-50%)'; + } else { + // arrow pointing leftwards from left border into cell (originates from definition at left) + arrow.innerHTML = ''; + arrow.style.left = '0px'; + arrow.style.top = '50%'; + arrow.style.transform = 'translateY(-50%)'; } + targetEl.appendChild(arrow); } } - // Vertical-definition mapping - if (defCell.definitionV) { - const tr = dr + 1; - const tc = dc; - if (tr >= 0 && tr < grid.length && tc >= 0 && tc < grid[0].length) { - const targetEl = window._cellEls[tr] && window._cellEls[tr][tc]; - if (targetEl) { - const arrow = document.createElement('div'); - arrow.className = 'def-arrow'; - if (dc === 0) { - // left-edge special: curve right - arrow.innerHTML = ''; - arrow.style.position = 'absolute'; - arrow.style.left = '2px'; - arrow.style.top = '50%'; - arrow.style.transform = 'translateY(-50%)'; - } else { - // up-pointing arrow near top border - arrow.innerHTML = ''; - arrow.style.position = 'absolute'; - arrow.style.top = '4px'; - arrow.style.left = '50%'; - arrow.style.transform = 'translateX(-50%)'; - } - arrow.style.pointerEvents = 'none'; - arrow.classList.add('def-arrow'); - targetEl.appendChild(arrow); + // Vertical mapping: def at (dr,dc) -> word starts at (dr+1,dc) normally + let trV = dr + 1; + let tcV = dc; + // left-column special: vertical definition maps to horizontal word starting at (dr+1,dc) + let verticalIsHorizontal = false; + if (dc === 0) { + verticalIsHorizontal = true; + trV = dr + 1; + tcV = dc; + } + + if (defCell.definitionV && trV < grid.length) { + const targetEl = window._cellEls[trV] && window._cellEls[trV][tcV]; + if (targetEl) { + const arrow = document.createElement('div'); + arrow.className = 'def-arrow'; + if (verticalIsHorizontal) { + // arrow rightwards from left border + arrow.innerHTML = ''; + arrow.style.left = '0px'; + arrow.style.top = '50%'; + arrow.style.transform = 'translateY(-50%)'; + } else { + // arrow pointing upwards from top border? we want from definition to word, so arrow downwards from top border + arrow.innerHTML = ''; + arrow.style.top = '0px'; + arrow.style.left = '50%'; + arrow.style.transform = 'translateX(-50%)'; } + targetEl.appendChild(arrow); } } } @@ -977,19 +1010,24 @@ } } - // Gestion du clavier + // Gestion du clavier (saisie, navigation, suppression) document.addEventListener('keydown', (e) => { - if (!activeCell || document.getElementById('gridScreen').style.display === 'none') return; - - const { row, col } = activeCell; - + // don't intercept when modifier keys are pressed + if (e.ctrlKey || e.altKey || e.metaKey) return; + if (document.getElementById('gridScreen').style.display === 'none') return; + + // Toggle orientation with Tab when an active cell exists if (e.key === 'Tab') { + if (!activeCell) return; e.preventDefault(); orientation = orientation === 'horizontal' ? 'vertical' : 'horizontal'; renderGrid(); return; } - + + if (!activeCell) return; + const { row, col } = activeCell; + if (e.key === 'Backspace') { e.preventDefault(); if (grid[row][col].letter) { @@ -1014,27 +1052,27 @@ } return; } - + if (e.key.startsWith('Arrow')) { e.preventDefault(); let newRow = row; let newCol = col; - + if (e.key === 'ArrowUp') newRow = Math.max(0, row - 1); if (e.key === 'ArrowDown') newRow = Math.min(grid.length - 1, row + 1); if (e.key === 'ArrowLeft') newCol = Math.max(0, col - 1); if (e.key === 'ArrowRight') newCol = Math.min(grid[0].length - 1, col + 1); - + activeCell = { row: newRow, col: newCol }; renderGrid(); return; } - + if (e.key.length === 1 && /[a-zA-Z]/.test(e.key)) { e.preventDefault(); - + if (grid[row][col].type !== 'letter') return; - + // Crée automatiquement une case définition si nécessaire if (orientation === 'horizontal' && col > 0) { const prevCell = grid[row][col - 1]; @@ -1047,9 +1085,9 @@ prevCell.type = 'definition'; } } - + grid[row][col].letter = e.key.toUpperCase(); - + // Avance à la case suivante if (orientation === 'horizontal' && col < grid[0].length - 1) { let nextCol = col + 1; @@ -1068,16 +1106,7 @@ activeCell = { row: nextRow, col }; } } - - renderGrid(); - } - }); - // Ensure tab toggles orientation even if focus is elsewhere - document.addEventListener('keydown', (e) => { - if (e.key === 'Tab') { - e.preventDefault(); - orientation = orientation === 'horizontal' ? 'vertical' : 'horizontal'; renderGrid(); } }); diff --git a/mots.txt b/mots.txt index 4d5fb89..43f2056 100644 --- a/mots.txt +++ b/mots.txt @@ -1,5 +1,27 @@ chat: doux mais violent +chat: doux mais violent violent violent violent violent chat: mais violent +chat: mais violent +chat: mais violenta +chat: mais violentu +chat: mais violenti +chat: mais violente +chat: mais violent, +chat: mais violentc +chat: mais violentt +chat: mais violents +chat: mais violentr +chat: mais violentn +chat: mais violentb +chat: mais violenté +chat: mais violentp +chat: mais violento +chat: mais violentè +chat: mais violent +chat: mais violentôv +chat: mais violentd +chat: mais violentl +chat: mais violentj plante: assoiffée de calme président: affiné un mandat président: affiné pour un mandat